publishing-api: Publishing API's API
This is the primary interface from publishing apps to the publishing pipeline.
Applications PUT items as JSON conforming to a schema specified in the content_schemas directory.
Content locations are arbitrated internally by the Publishing API, the content
is then forwarded to the live and draft content stores, and placed on the
message queue for other apps (e.g. email-alert-service) to consume.
Endpoints
PUT /v2/content/:content_idPOST /v2/content/:content_id/publishPOST /v2/content/:content_id/republishPOST /v2/content/:content_id/unpublishPOST /v2/content/:content_id/discard-draftGET /v2/contentGET /v2/content/:content_idGET /v2/content/:content_id/host-contentGET /v2/content/:content_id/host-content/:host_content_idGET /v2/content/:content_id/eventsPATCH /v2/links/:content_idGET /v2/links/:content_idGET /v2/expanded-links/:content_idGET /v2/linked/:content_idGET /v2/linkablesGET /v2/links/changesGET /v2/editionsPOST /v2/links/by-content-idGET /v2/schemasGET /v2/schemas/:schema_namePOST /lookup-by-base-pathPUT /paths/:base_pathDELETE /paths/:base_pathPUT /publish-intent(/*base_path)DELETE /publish-intent(/*base_path)
Optimistic locking (previous_version)
All PUT and POST endpoints take an optional JSON attribute previous_version
in the request. If given, the corresponding value should be a integer. This
allows the Publishing API to check that the publishing app sending the request
intends to update the latest lock version of the model in question.
If previous_version is provided, the Publishing API will confirm that the
provided value matches that of the edition in the Publishing API. If it
does not, a 409 Conflict response will be provided.
Warnings
Some endpoints may return warnings along with the content. For those that do, in the top level object for the content, there will be a value named "warnings". This will be an object, where the names are the warnings that are applicable, and the corresponding values are a human readable description of the warning.
Content Item Blocking Publish
This warning is only applicable for documents with an edition in a draft state, and indicates that the draft cannot be published due to the presence of an edition of a different at the base_path this edition is using.
Some document types are exempt from this restriction, and if either the draft, or the blocking edition are of a "substitutable" document type, upon the publish of the draft, the blocking item will be unpublished.
PUT /v2/content/:content_id
Used to create or update a draft edition of a document. It will restrict
creation if there is different document with a draft edition using the same
base_path. Uses optimistic-locking.
The request must conform to the schema. If it does not, a 422 response will be returned.
If the request is successful, this endpoint will respond with the presented edition and warnings.
Path parameters
-
content_id- Specifies the
content_idof the content to be created or updated.
- Specifies the
JSON attributes
-
access_limited(optional)- A JSON object with a key of "users" the value of which is a array of UUIDs identifying users.
- If provided, only the specified users will be able to view the content item on the draft frontend applications. It has no effect on live content.
-
analytics_identifier(optional)- An identifier to track the content item in analytics software.
-
base_path(conditionally required)- Required if
schema_nameis not one of "contact" or "government". - The path that this item will use on GOV.UK.
- Required if
-
change_note(optional)- Specifies the change note.
- Ignored if the
update_typeis not "major" or "content_block".
-
description(optional)- A description of the content that can be displayed publicly.
-
details(conditionally required, default: {})- JSON object representing data specific to the
document_type. - If there is no top-level
change_noteattribute, and this is a "major"update_type, then the Publishing API may extract thechange_notefrom the details hash.- If
detailshas a member namedchange_note, that is used. - Otherwise, if
detailscontains a member namedchange_history, then thenotewith the latest correspondingpublic_timestampis used.
- If
- JSON object representing data specific to the
-
document_type(required)- A particular type of document, used to differentiate between documents that are of different types but share the same schema.
-
first_published_at(optional)- Specifies the first_published_at date from the publishing app.
-
last_edited_at(optional)- An RFC 3339 formatted timestamp should be provided, although other formats may be accepted.
- Specifies when this edition was last edited.
- If omitted and
update_typeis "major" or "minor"last_edited_atwill be set to the current time.
-
links(optional, default: {})- A JSON object containing arrays of
content_ids for eachlink_type. - Applicable
link_types are defined in the schema for this document_type.
- A JSON object containing arrays of
-
locale(optional, default: "en")- Accepts: An available locale from the Rails I18n gem
- Specifies the locale of the edition.
-
phase(optional, default: "live")- Accepts: "alpha", "beta", "live"
-
previous_version(optional, recommended)- Used to ensure that the most recent version of the draft is being updated.
-
public_updated_at(optional)- Used to override the
public_updated_atvalue that would be set by the Publishing API. - An RFC 3339 formatted timestamp should be provided, although other formats may be accepted.
- Used to override the
-
publishing_app(required)- The hostname for the publishing application that has sent this content.
-
redirects(conditionally required)- Required for a
document_typeof "redirect". - An array of redirect values. (TODO: link directly to example)
- Required for a
-
rendering_app(conditionally required)- Required for a
document_type(orformat) that is not "redirect" or "gone". - The hostname for the frontend application that will eventually render this content.
- Required for a
-
routes(conditionally required)- Required for a
document_typethat is not "redirect". - An array of route values.
- Required for a
-
schema_name(required)- The name of the schema that the request body will be validated against.
-
title(conditionally required)- Required for a
document_typethat is not "redirect" or "gone".
- Required for a
-
update_type(optional)- Accepts: "major", "minor", "republish"
- It is acceptable to send a "minor" update for the first ever draft
-
bulk_publishing(optional, default: false)- Set this to true when making multiple requests. Publishing API will use a lower priority queue to avoid delays to standard publishing activity.
State changes
- If a
base_pathis provided it is reserved for use of the givenpublishing_app. - If this is changing the
base_pathof a draft edition the previousbase_pathreserved will be discarded. - Any draft editions for different documents that have a matching
base_pathand have a document_type of "coming soon", "gone", "redirect" or "unpublishing" will be deleted. - If an edition for this document already exists in a "draft" state:
- The existing draft edition will be updated.
- If the
base_pathhas changed since the last update, a draft redirect will be created.
- If an edition for this document does not exist in a "draft" state:
- A new edition will be created
- If the
base_pathis different to that of the published edition (if this exists) a draft redirect will be created.
- The draft content store will be updated with the edition and any associated redirects.
POST /v2/content/:content_id/publish
Transitions an edition from a draft state to a published state. The edition will be presented in the live content store. Uses optimistic-locking.
Path parameters
-
content_id- Identifies the document which has an edition to publish.
JSON attributes
-
update_type(conditionally required, deprecated)- Accepts: "major", "minor", "republish"
- Will fallback to the
update_typeset when the draft was created if not specified in the request. - This is deprecated, clients should instead set the update type when putting the content.
-
locale(optional, default: "en")- Accepts: An available locale from the Rails I18n gem
- Specifies the locale of the document.
-
previous_version(optional, recommended)- Used to ensure that the version being published is the most recent draft update to the document.
State changes
- The draft edition for a document matching
content_idandlocalewill change state to "published" - Any previously published editions for this document will have their state set to "superseded".
- For an
update_typeof "major" thepublic_updated_atfield will be updated to the current time. - For an
update_typeother than "major" or "content_block":- If it exists, the change note will be deleted, as change notes are only for major updates.
- If the edition has a non-blank
base_path:- If the
base_pathof the draft item differs to the published version of this edition:- Redirects to this edition will be published.
- Any published editions that have a matching
base_pathand have a document_type of "coming soon", "gone", "redirect" or "unpublishing" will have their state changed to "unpublished" with a type of "substitute". - The live content store will be updated with the published edition and any associated redirects.
- All published editions that link to this item (directly or through a recursive chain of links) will be updated in the live content store.
- If the
POST /v2/content/:content_id/republish
Used to set a live edition to a published state, used to remove unpublishing or to re-send published data downstream. Uses optimistic-locking.
Path parameters
-
content_id- Identifies the document which has an edition to republish.
JSON attributes
-
locale(optional, default: "en")- Accepts: An available locale from the Rails I18n gem
- Specifies the locale of the document.
-
previous_version(optional, recommended)- Used to ensure that the version being published is the most recent draft update to the document.
State changes
- Any unpublished editions will have their status set back to published
- The publishing_request_id for an edition will be updated
- The live content store will be updated with the published edition
- The draft content store will be updated unless the document has a draft edition
- All published editions that link to this item (directly or through a recursive chain of links) will be updated in the live content store.
POST /v2/content/:content_id/unpublish
Transitions an edition of a document into an unpublished state. The edition will be updated or removed from the live content store depending on the unpublishing type. Uses optimistic-locking.
Path parameters
-
content_id- Identifies the document which will have an edition unpublished.
JSON attributes
-
allow_draft(optional)- Boolean value, cannot be
trueifdiscard_draftsis alsotrue. - Specifies that only a draft edition will be unpublished.
- Boolean value, cannot be
-
alternative_path(conditionally required)- Required for a
typeof "redirect" (ifredirectsis not given), Optional for atypeof "gone". - If specified, this should be a
base_path.
- Required for a
-
redirects(conditionally required)- Required for a
document_typeof "redirect" (ifalternative_pathis not given). - An array of redirect values similar to that which can be passed to
PUT /v2/content/:content_id.
- Required for a
-
discard_drafts(optional)- Boolean value, cannot be
trueifallow_draftsis alsotrue. - Specifies that if a draft exists, it will be discarded.
- Boolean value, cannot be
-
explanation(conditionally required)- Required for a
typeof "withdrawal", Optional for a type of "gone". - Message that will be displayed publicly on the page that has been unpublished.
- Required for a
-
locale(optional, default: "en")- Accepts: An available locale from the Rails I18n gem
- Specifies the document to unpublish.
-
previous_version(optional, recommended)- Used to ensure that the version being unpublished is the most recent version of the document.
-
type(required)- Accepts: "gone", "redirect", "withdrawal", "vanish"
- The type of unpublishing that is being performed.
-
unpublished_at(optional)- An RFC 3339 formatted timestamp should be provided, although other formats may be accepted.
- Specifies a publisher provided time of when this content was removed/withdrawn.
- Used to override the
withdrawn_attime provided to content store, for withdrawn documents content.
State changes
- If the unpublishing
typeis "gone", "redirect" or "withdrawal":- If the document matching
content_idandlocalehas a draft state andallow_draftistrue:- The draft edition state is set to "unpublished".
- If a previously published version of the edition exists it's state will be set to "superseded".
- If the document matching
content_idandlocalehas a draft anddiscard_draftsistrue:- The draft edition will be deleted from the Publishing API.
- The draft edition will be removed from the draft content store.
- The published edition state is set to "unpublished".
- If the document matching
content_idandlocalehas no draft:- The published edition state is set to "unpublished".
- The live content store will be updated with the unpublished edition.
- All published editions that link to this item (directly or through a recursive chain of links) will be updated in the live content store.
- If the document matching
- If the unpublishing
typeis "vanish":- The edition will be removed from the live content store.
POST /v2/content/:content_id/discard-draft
Deletes a draft edition of a document. Replaces the draft content item on the draft content store with the published item, if one exists. Uses optimistic-locking.
Path parameters
-
content_id- Identifies the document with a draft edition.
JSON attributes
-
locale(optional, default: "en")- Accepts: An available locale from the Rails I18n gem
- With content_id, specifies the document with a draft edition.
-
previous_version(optional, recommended)- Used to ensure the edition being discarded is the current draft.
State changes
- The draft edition will be deleted from the Publishing API.
- Any reserved paths unique to the draft edition will also be discarded.
- The draft edition will be removed from the draft content store.
- If a published edition exists it will be added to the draft content store.
GET /v2/content
Retrieves a paginated list of editions for the provided query string parameters. If editions exists in both a published and a draft for a document and a state has been specified, the draft is returned.
Query string parameters
-
document_type(optional)- The type of editions to return.
-
fields[](optional)- Accepts an array of: analytics_identifier, base_path, content_id_aliases, content_store, description, details, document_type, first_published_at, last_edited_at, major_published_at, phase, public_updated_at, published_at, publishing_api_first_published_at, publishing_api_last_edited_at, publishing_app, redirects, rendering_app, routes, schema_name, state, title, user_facing_version, update_type
- Determines which fields will be returned in the response, if omitted all fields will be returned.
-
link_*(optional)- Accepts a content_id.
- Used to restrict documents to those linking to another document,
e.g.
link_organisations=056a9ff6-2ed1-4942-9f06-92df03da741dwill restrict the documents returned to those that have a link with typeorganisationsto the document with specified content id.
-
locale(optional, default "en")- Accepts: An available locale from the Rails I18n gem
- Used to restrict documents to a given locale.
-
order(optional, default: "-public_updated_at")- The field to sort the results by.
- Returned in an ascending order unless prefixed with a hyphen, e.g. "-base_path".
-
page(optional, default: 1)- The page of results requested.
-
per_page(optional, default: 50)- The number of results to be shown on a given page.
-
q(optional)- Search term to match against the fields in
search_in[].
- Search term to match against the fields in
-
search_in[](optional, default: [title, base_path])- Array of fields to search against.
- Fields supported are
title,base_path,description, anddetails.*- where * indicates a field within details, e.g.details.internal_name.
-
publishing_app(optional)- Used to restrict editions to those for a given publishing app.
-
states(optional)- Used to restrict editions to those in the specified states.
-
content_id_aliases[](optional)- Accepts an array of content_id_aliases.
- Used to restrict editions to those which have a given content_id_alias associated with them
GET /v2/content/:content_id
Retrieves a single edition of a document for a content_id and locale. By
default the most recent edition is returned, which may be a draft.
If the returned item is in the draft state, warnings may be included within the response.
Path parameters
-
content_id- Identifies the document to be returned.
Query string parameters
-
locale(optional, default "en")- Accepts: An available locale from the Rails I18n gem
- Used to return a specific locale.
-
version(optional)- Specify a particular edition of this document
- If omitted the most recent edition.
GET /v2/content/:content_id/events
Retrieves a list of all events for a given :content_id
Path parameters
-
content_id- Identifies the document to return events for
Query parameters
-
action(optional)- Specify what action type to filter for
- If omitted, returns all actions
-
from(optional)- Filter for actions created after that particular datetime
-
to(optional)- Filter for actions created before that particular datetime
GET /v2/content/:content_id/host-content
Retrieves a summary list of content which has an embedded reference to the target :content_id.
Content can include an embedded reference in its body when it wants to defer to a reusable piece of content, such as an email address.
Path parameters
-
content_id- Identifies the target document for the reusable piece of content
Query parameters
-
order(optional, default: "unique_pageviews")- The field to sort the results by.
- Returned in an ascending order unless prefixed with a hyphen, e.g. "-title".
-
page(optional, default: "1")- The page number of results to return
GET /v2/content/:content_id/host-content/:host_content_id
Returns metadata for a single item of content with ID :host_content_id that has an embedded reference to
the target :content_id.
Path parameters
-
content_id- Identifies the target document for the reusable piece of content
-
host_content_id- Identifies the document to return the metadata for
Query parameters
-
locale(optional, default: "en")- An optional locale to filter by
PATCH /v2/links/:content_id
Creates or updates a set of links for the given content_id. Link sets can be
created before or after the PUT request for the
content. These are tied to documents solely by matching content_id and they
are not associated with a locale or a particular edition. The ordering of links
in the request is preserved.
Path parameters
-
content_id- Identifies the documents the links are for.
JSON attributes
-
links(required)- A JSON object containing arrays of
content_ids for eachlink_type. - An empty array for a
link_typewill delete thatlink_type.
- A JSON object containing arrays of
{
"links": {
"organisations": [
"591436ab-c2ae-416f-a3c5-1901d633fbfb"
],
"unwanted_link_type": []
}
}
-
previous_version(optional, recommended)- Used to ensure that we are updating the current version of the link set.
-
bulk_publishing(optional, default: false)- Set this to true when making multiple requests. Publishing API will use a lower priority queue to avoid delays to standard publishing activity.
State changes
- A link set is created or updated, with the
lock_versionof the link set being incremented. - The draft content store is updated if there are editions of documents
matching the
content_idon the draft content store. - The live content store is updated if there are editions of documents
matching the
content_idon the live content store.
GET /v2/links/:content_id
Retrieves only the link set links for the given content_id.
Returns arrays of content_ids representing documents. These are grouped by
link_type. The ordering of the returned links matches the ordering when they
were created.
Path parameters
-
content_id- Identifies the documents links will be retrieved for.
GET /v2/expanded-links/:content_id
Retrieves the expanded link set for the given content_id. Returns arrays of
details for each linked edition in groupings of link_type.
To ensure fast performance the result for this is pulled from a database which is updated whenever the content store is updated. This may mean that if you update links and then request this endpoint you may get a stale response.
You can request a fresh response by adding a query string of generate=true,
this response can be slow though for large link sets.
The response includes a field of generated and the timestamp of when the
expanded link set was generated.
If the links are generated at runtime (which happens if use generate=true)
a version field will be returned which will be the stale_lock_version for
the LinkSet of that content_id. This is a deprecated field and should not be
used as it is not a reliable indicate of the version of the links.
Path parameters
-
content_id- Identifies the link set links will be retrieved for.
Query string parameters:
-
locale(optional, default: "en")- Accepts: An available locale from the Rails I18n gem
-
with_drafts(optional, default: true)- Whether links to draft editions should be included in the response.
-
generate(optional, default: false)- Whether to generate the expanded links at request time, ensures a fresh response but could make the request slow
GET /v2/linked/:content_id
Retrieves all editions that have link set links to the given content_id
for some link_type.
Path parameters
-
content_id- Identifies the link set editions may be linked to.
Query string parameters
-
link_type(required)- The type of link between the documents.
-
fields[](required)- Accepts an array of: analytics_identifier, base_path, content_store, description, details, document_type, first_published_at, last_edited_at, phase, public_updated_at, publishing_app, redirects, rendering_app, routes, schema_name, state, title, user_facing_version, update_type, state
- Determines which fields will be returned in the response.
GET /v2/linkables
Returns abridged versions of all editions matching the given
document_type. Returns title, content_id, publication_state, base_path
from the document and edition. It also adds a special field internal_name,
which is details.internal_name and falls back to title.
Query string parameters:
-
document_type(required)- The
document_typevalue that returned editions has.
- The
GET /v2/links/changes
Returns an array of changes to links, giving the information on what changed (source and target content ids, and the link type), when the change happened, what user was associated with the action, and if the link was created or deleted.
The results will be in descending order by date, so newer changes come before older changes. A maximum of 250 changes will be returned.
Query string parameters
-
link_types[](required)- Filter the changes by link type.
-
source_content_ids[]- Filter the changes by source content id.
-
target_content_ids[]- Filter the changes by source content id.
-
users[]- Filter the changes by user UIDs.
GET /v2/editions
Retrieves a paginated list of editions for the provided query string parameters.
Query string parameters
-
document_type(optional)- The type of editions to return.
-
fields[](optional)- Accepts an array of: analytics_identifier, base_path, content_id, content_store, created_at, description, details, document_type, first_published_at, last_edited_at, links, locale, major_published_at, phase, public_updated_at, published_at, publishing_api_first_published_at, publishing_api_last_edited_at, publishing_app, redirects, rendering_app, routes, schema_name, stale_lock_version, state, title, user_facing_version, update_type, updated_at
- Determines which fields will be returned in the response, if omitted all fields will be returned.
-
locale(optional)- Accepts: An available locale from the Rails I18n gem
- Used to restrict documents to a given locale.
-
order(optional, default: "updated_at")- The field to sort the results by.
- Returned in an ascending order unless prefixed with a hyphen, e.g. "-created_at".
- Accepts fields of: updated_at, public_updated_at, created_at, id
-
beforeandafter(optional)- The pagination key of the previous page to pagination before or after.
- Usually, you do not need to work this out manually, since it will be given
to you in the
linkshash of the response. - The format is a comma separated string of the values of the pagination keys for the page you want.
-
per_page(optional, default: 100)- The number of results to be shown on a given page.
-
publishing_app(optional)- Used to restrict editions to those for a given publishing app.
-
states[](optional)- Used to restrict editions to those in the specified states.
POST /v2/links/by-content-id
Retrieves the set of links for a given collection of content_ids. Returns a
mapping of content_id to links hash.
POST parameters:
-
content_ids[](required)- An array of
content_ids to query by. This can be no longer than 1000 ids, or the API will return a 413 error.
- An array of
GET /v2/schemas
Lists all the schemas used by Publishing API. Returns an a mapping of a schema name to its JSON schema.
GET /v2/schemas/:schema_name
Gets a schema by its name. Returns the relevant JSON schema if found, 404 if not.
POST /lookup-by-base-path
Retrieves live editions for a given collection of base paths. Returns
a mapping of base_path to content_id.
POST parameters:
-
base_paths[](required)- An array of
base_paths to query by.
- An array of
- 'exclude_unpublishing_types[]' (optional, default: ['vanish', 'redirect', 'gone'])
- Content with these unpublishing types will be excluded from the lookup
- 'exclude_document_types[]' (optional, default: ['gone', 'redirect'])
- Content with these documents types will be excluded from the lookup
PUT /paths/:base_path
Reserves a path for a publishing application. Returns success or failure only.
Path parameters
-
base_path- Identifies the path that will be reserved
JSON parameters:
-
publishing_app(required)- The name of the application making this request, words separated with hyphens.
-
override_existing(optional)- Explicitly claim a path that has already been reserved by a different publishing_app. If not true, attempting to do this will fail.
State changes
- If no path reservation for the supplied base_path is present, one will be created for the supplied publishing_app.
- If a path reservation exists for the supplied base_path but a different
publishing_app, and
override_existingis not true, the command will fail. - If a path reservation exists for the supplied base_path and a different a
publishing_app, and
override_existingis true, the existing reservation will be updated to the supplied publishing_app.
DELETE /paths/:base_path
[Request/response detail][unreserve-path-pact]
Unreserves a path for a publishing application. Returns success or failure only.
Path parameters
-
base_path- Identifies the path that will be unreserved
JSON parameters:
-
publishing_app(required)- The name of the application making this request, words separated with hyphens.
State changes
- If no path reservation for the supplied base_path is present, the command will fail.
- If a path reservation exists for the supplied base_path but a different publishing_app, the command will fail.
PUT /publish-intent(/*base_path)
Used to create or update a publishing intent for a particular base_path and reserve the base path in the publishing-api. A publishing intent sets when the cache should expire for a piece of content.
Path parameters
-
base_path- Identifies the path to create the publishing intent for
JSON parameters:
-
publishing_app(required)- The name of the application making this request.
-
rendering_app(required)- The name of the application rendering the content the base path refers to.
-
publish_time(required)- The
DateTimethe content is set to be published.
- The
-
routes(optional)-
Array- Fields supported are path and type, the exact requirements can be found here. This is optional as it is only required if there needs to be a route created in router-api for thebase_pathat the same time the publishing intent is made.
-
State changes
-
base_pathis reserved for use of the givenpublishing_app. - Creates a
PublishingIntentin content-store to record when the cache should expire for abase_path. - If
routesare given, adds a route set in router-api.
DELETE /publish-intent(/*base_path)
Used to delete the publishing intent for a particular base_path. Removing a
publishing intent means that the content will continue to be cached as
normal.
Path parameters
-
base_path- Identifies the path to delete the publishing intent for
State changes
- The
PublishingIntentfor the passed in base_path is removed from the content-store.