Sending Multiple ANS Objects to Arc XP Services Using Migration Center
As a developer for an organization moving its content from a legacy CMS to Arc XP, you have worked to map the source fields from your legacy CMS content and are writing the adapter that transforms the legacy content into ANS and moves the ANS into Arc XP applications. You will be using the Migration Center APIs. You have an example source document from a legacy CMS that you will work out how to send through Migration Center. The source document is a story, and that story contains an image. You realize that to fully convert this story so that it looks the same in Arc XP means that you also will need to convert the image, resulting in two items of ANS to send to Arc XP.
With the transformed story and image ANS at hand, you can explore the options of how to send both these ANS items through to the Arc XP services using Migration Center.
Option 1: Migration Center API /ans
Endpoint
The /ans
API endpoint is used to send a single piece of ANS into the Arc XP system. The endpoint accepts a POST with a few optional query parameters and a payload of a Migration Center JSON object formatted with specific keys. One of the keys in the Migration Center JSON object holds the ANS object. Other keys provide instructions that control the downstream API requests that Migration Center will be making.
You can include three query parameters with the /ans
API endpoint:
website
: If used, this value becomes a tag the MC reports. You can query Migration Center’s reporting API/summary
endpoint to find all requests that were tagged as belonging to this value. The value of this parameter should be the ANS content’s primary website ID.groupId
: If used, this value is an arbitrary value used to tag requests coming through the MC API. You can query content flagged with the same groupId value by using the MC Reporting API.priority
: input eitherhistorical
orlive
values. This parameter is applicable only when sending a story object in the ANS key. This value sets theArc-Priority
header in Draft API. If not included, the MC API defaults this value tohistorical
.
curl --request POST \ --url 'https://api.{{org}}.arcpublishing.com/migrations/v3/content/ans ?website=my-website-id &groupId=ingested-on-march11 &priority=historical' \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{...}' // the Migration Center JSON object
Send one request per ANS object to the /ans
endpoint
Sending the story and image through Migration Center requires two separate calls to the /ans
API endpoint. In order to query the Migration Center Reporting API and return only these two records, filtering out all past Migration Center ingestions, you must attach filter values to each record. You can make use of the optional query parameters available on the /ans
API endpoint, passing the same website=
and groupId=
query parameters in each request.
Migration Center API JSON object for /ans
endpoint
The JSON object sent in the payload of the /ans
API endpoint has one required key, ANS
, which holds the ANS of an Arc XP object. The ANS in this key is validated when the request is submitted, and the request fails if the ANS is poorly constructed.
ANS
: The JSON of the Arc XP content object: a story, gallery, video, image, tag, or author object.circulation
: The JSON of a story’s circulation data. This key is applicable only when a story object is in theANS
key.operation
: A JSON object containing data that registers a future publication operation on a story. This key is applicable only when a story object is in the ANS key.arcAdditionalProperties
: A JSON object that contains commands to affect the behavior of specific downstream Arc XP APIs. Migration Center constructs calls to these APIs depending on the ANS type. This key is applicable only when a story or video object is in the ANS key.
{ "ANS": {}, // the ANS JSON "circulation": [], // circulations for a story document "operation": [], // scheduled publishing operations for a story document "arcAdditionalProperties": {} // additional commands controlling the migration process, broken down by ANS type}
Request 1: Story
- is sending story ANS
- is sending a story circulation
- is sending MC reporting tags in the query parameters
curl --request POST \ --url 'https://api.{{org}}.arcpublishing.com/migrations/v3/content/ans ?website=my-website-id &groupId=ingested-on-march11 \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data ' { "ANS": { "type": "story", "version": "0.10.7", "_id": "ANSIDAND26MORECHARACTERS", "headlines": { "basic": "The origin of the bicycle, a history" }, "source": { "system": "alc", "source_id": "123" }, "owner": { "id": "{{org}}" } }, "circulation": [{ "document_id": "ANSIDAND26MORECHARACTERS", "website_id": "cyclist-daily", "website_url": "/main/origin-of-bicycle-history/", "website_primary_section": { "type": "reference", "referent": { "id": "/main", "type": "section", "website": "cyclist-daily" } }, "website_sections": [ { "type": "reference", "referent": { "id": "/main", "type": "section", "website": "cyclist-daily" } } ] }] }'
Request 2: Image
- is sending image ANS
- is sending Migration Center reporting tags in the query parameters
curl --request POST \ --url 'https://api.{{org}}.arcpublishing.com/migrations/v3/content/ans ?website=my-website-id &groupId=ingested-on-march11 \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data ' { "ANS": { "type": "image", "version": "0.10.7", "_id": "ANSIDFORANIMAGESTILL26CHARS", "owner": { "id": "{{org}}" }, "source": { "system": "Unsplash", "source_id": "1555848960-c881e30379c" }, "additional_properties": { "originalName": "olympic-medal.jpg", "version": 0, "originalUrl": "https://images.unsplash.com/photo-1555848960-c881e30379c0" } } }'
Option 2: Migration Center API /bulk
Endpoint
Migration Center has a /bulk
API endpoint that allows you to send both the story and image ANS objects in one request. When using the /bulk
API endpoint, the structure of the Migration Center JSON object changes. Migration Center JSON for /bulk
API allows a list of ANS objects to be part of the request payload, and adds extra keys per object to hold what had been query parameters on the /ans
endpoint.
curl --request POST \ --url 'https://api.{{org}}.arcpublishing.com/migrations/v3/content/ans/bulk \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{...}' // Migration Center JSON objects for /bulk
Notice that the /bulk
endpoint does not support query parameters at the endpoint’s URL. These are represented instead in the Migration Center JSON object for /bulk
.
Migration Center API JSON object for /bulk endpoint
The /bulk
version of the Migration Center JSON object contains four top-level keys:
content
- Contains a list of objects. Each item in this list contains the information about an ANS document and the Migration Center request options that affect the object. See our maximum and recommended number of items below.defaultPriority
- Provides the default value forArc-Priority
header. All items with story ANS in thecontent
key use this value, unless it is overridden specifically per ANS object.defaultWebsite
,defaultGroupId
- Provides the default value for filter that you can use with the/report
API endpoint. You can override these keys per ANS object in the content list.
The /ans
version of the Migration Center JSON object is reused as a nested object in the /bulk
Migration Center JSON, as item in the content list. When used in this list, the objects also can contain three optional keys to mimic the query parameters accepted by the /ans
API endpoint. If used, these nested values override any default values set by the top level /bulk
Migration Center JSON keys defaultPriority
, defaultWebsite
, and defaultGroupId
.
In one call to the /bulk
API endpoint, you can pass up to 50 nested objects in the content
key. We recommend limiting the number of items to 25 to optimize bulk ingestion.
// MC JSON object for /bulk { "defaultPriority": "historical", "defaultWebsite": "my-website", "defaultGroupId": "test_batch_bicycles", "content": [ // MC json object normally used at /ans endpoint { "ANS": { ... }, // queried for in reporting api using filters website: my-website and groupId: test_batch_bicycles "circulation": [], "operation": [], "arcAdditionalProperties": {} }, // /ans MC JSON object and keys that overrride default values set in the parent object { "ANS": { ... }, // queried for in reporting api using filters website: my-website2 and groupId: test-batch-2 "priority": "live", "website": "my-website2", "groupId": "test-batch-2" }, { "ANS": { ... } // queried for in reporting api using filters website: my-website and groupId: test_batch_bicycles } // up to 50 ANS documents allowed ] }
The example shows that you can override the default values set in the parent object by including specific keys in the objects in the content list. However, this is not necessarily the best idea. The best practice if you are sending many objects through the /bulk
API is to have them all carry the same filters and priority so you can query for just these items at the /report
API endpoint.
Additionally, you should always use the historical
priority value when migrating content from a legacy CMS.
Behind the scenes, the /bulk
API endpoint splits the content key into separate requests. If the objects in the content list have specific values for priority, website or group ID, then those values are applied in place of the default values. Otherwise, the defaults at the top level of the payload are applied to all items in the content list. Because each content item results as a separate request, when a POST to the /bulk
endpoint is successful, the API returns a very generic message saying that only the request was accepted.
// 202 Accepted{ "success": true, "message": "Bulk ANS content has been accepted and added to the queue for migration."}
To check on the status of the items in the POST to /bulk
, you must construct a /report/detail
API call for each separate ANS ID contained in the content list. Or, if you included values in the defaultWebsite
, defaultGroupId
, content.website
, or content.groupId
keys, you can query the /report/summary
API endpoint to filter for only these records.
Sending one request for up to 50 ANS objects to the /bulk endpoint
Because the /bulk
API endpoint can accept up to 50 ANS records, we can use this to send both the story and the image into Arc XP.
curl --request POST \ --url 'https://api.{{org}}.arcpublishing.com/migrations/v3/content/ans/bulk \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data ' { "defaultPriority": "historical", "defaultWebsite": "my-website", "defaultGroupId": "ingested-on-march11", "content": [ { "ANS": { "type": "story", "version": "10.0.7", "_id": "ANSIDAND26MORECHARACTERS", "headlines": { "basic": "The origin of the bicycle, a history" }, "source": { "system": "alc", "source_id": "123" }, "owner": { "id": "{{org}}" } }, "circulation": [{ "document_id": "ANSIDAND26MORECHARACTERS", "website_id": "cyclist-daily", "website_url": "/main/origin-of-bicycle-history/", "website_primary_section": { "type": "reference", "referent": { "id": "/main", "type": "section", "website": "cyclist-daily" } }, "website_sections": [ { "type": "reference", "referent": { "id": "/main", "type": "section", "website": "cyclist-daily" } } ] }] }, { "ANS": { "type": "image", "version": "0.10.7", "_id": "ANSIDFORANIMAGESTILL26CHARS", "owner": { "id": "{{org}}" }, "source": { "system": "Unsplash", "source_id": "1555848960-c881e30379c" }, "additional_properties": { "originalName": "olympic-medal.jpg", "version": 0, "originalUrl": "https://images.unsplash.com/photo-1555848960-c881e30379c0" } } } ] }'
Reporting on Status
Use the /report
APIs to investigate status of the ANS items sent to the Arc XP services through the Migration Center APIs. No matter if the ANS items were sent through on the /ans
or /bulk
API endpoints, you must query the /report
APIs to uncover what happened with ANS after having been POSTed.
With the ANS ID of the object that was POSTed and the Arc XP content type, you can query for the full Migration Center record at the /report/detail
API endpoint. Both parameters are required.
// return the status details of the storycurl --request GET \ --url 'https://api.{{org}}.arcpublishing.com/migrations/v3/report/detail ?ansType=story &ansId=ANSIDAND26MORECHARACTERS' \ --header 'Authorization: Bearer <token>'
// return the status details of the imagecurl --request GET \ --url 'https://api.{{org}}.arcpublishing.com/migrations/v3/report/detail ?ansType=story &ansId=ANSIDFORANIMAGESTILL26CHARS' \ --header 'Authorization: Bearer <token>'
With the filter values from the /ans
endpoint’s query parameters, or included in the payload of the /bulk
endpoint, you can query for a series of status records at the /report/summary
API endpoint. The results include the ANS ID of each record that matches the filter terms. If necessary, you can take an ANS ID from the result and follow up with a query for its full detail at /report/detail
. You can filter /report/summary
by both website
and groupId
together, or filter individually.
curl --request GET \ --url 'https://api.{{org}}.arcpublishing.com/migrations/v3/report/summary ?website=my-website &groupId=ingested-on-march11' \ --header 'Authorization: Bearer <token>'
The /report/summary
API endpoint also works with just a status
query parameter. This filter will bring back results of all records with the status
state.
curl --request GET \ --url 'https://api.{{org}}.arcpublishing.com/migrations/v3/report/summary ?status=Success' \ --header 'Authorization: Bearer <token>'
Statuses: Pending, Queued, Processing, Success, Circulated, Published, ValidationFailed, FailStory
The /report/status/count
API endpoint shows the raw counts of how many items you have of each kind in each status. You can filter this endpoint by startDate
and endDate
in YYYY-MM-DD format, and the endpoint accepts two optional query parameters to sort items inside the response.
curl --request GET \ --url 'https://api.{{org}}.arcpublishing.com/migrations/v3/report/status/count ?startDate=2022-01-01 &endDate=2023-01-01 &sort=createDate &sortOrder=DESC' \ --header 'Authorization: Bearer <token>'
{ "historical": { "total": 11381, "ansTypes": { "gallery": { "FailGallery": 15, "Success": 54, "ValidationFailed": 9 }, "image": { "FailPhoto": 309, "Success": 6172, "ValidationFailed": 51 }, "story": { "Circulated": 8, "FailStory": 176, "Published": 4547, "ValidationFailed": 38 }, "video": { "FailVideo": 1, "Success": 1 } } }}