# How to use the Content Operations API

Source: https://dev.arcxp.com/publishing-platform/developer-docs/content-api/how-to-use-the-content-operations-api/

When you are importing content (conducting migrations, [ingesting wires](https://docs.arcxp.com/en/products/publishing-platform/how-to-ingest-wire-content-using-an-inbound-wires-adapter.html), or running a script), you may need to import content in a published or unpublished state, but schedule a publish, unpublish or deletion event in the future. This is the same as the Schedule/Unschedule button in Composer. The Content Operations API provides similar functionality to be scripted or added to your applications.

There are different operations available depending on the Arc XP content types (`story`, `image`, or `gallery`).

## Important Notes

- Calling the Content Ops API does not automatically update the `publishing.scheduled_operations[]`array in Arc XP Native Specification (ANS). This is mainly in order to provide you control of whether you want to make multiple changes without triggering story update events. If you **want** to have ANS updated, make your change with Content Ops API then call Draft API to make note of the update.
- Pay close attention to the content type fields and the name of the payload field that holds the `ans id`. This part of the payload often changes depending on the Arc XP content type.
- This is an administrative API only. The default rate limit for Content Operations API is 4 requests/second. If you are going to approach that limit, ensure that your code implements HTTP 429 response detection and retry logic.
- See the underscore **(\_)** and dash **(-)** differences in the tables below.
- Content Operations API calls do not work on the Arc XP `video` content type.

## API Operations

### PUT /publish

Schedules a publish event.

| Arc type | Payload Field: type                        | Payload Field: operation | Payload Field Name: ans id | Endpoint     |
| -------- | ------------------------------------------ | ------------------------ | -------------------------- | ------------ |
| story    | story\_operation                           | **publish\_edition**     | story\_id                  | **/publish** |
| gallery  | gallery-operation                          | update                   | \_id                       | **/publish** |
| image    | image-operation                            | update                   | \_id                       | **/publish** |
| video    | not applicable: videos cannot be scheduled | n/a                      | n/a                        | n/a          |

#### Story Publish Operation

```
curl --request PUT \
  --url https://api.<org or sandbox.org>.arcpublishing.com/contentops/v1/publish \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "story_operation",
    "story_id": "<ANSID>",
    "operation": "publish_edition",
    "date": "YYYY-MM-DDT00:00:00.000000+00:00"
}'
```

#### Image or Gallery Publish Operation

```
curl --request PUT \
  --url https://api.<org or sandbox.org>.arcpublishing.com/contentops/v1/publish \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "<image or gallery>-operation",
    "_id": "<ANSID>",
    "operation": "update",
    "date": "YYYY-MM-DDT00:00:00.000000+00:00"
}'
```

#### Operations API Responses

| Status Code     | Response Payload                                                                                                                                                                       | Reason for Response                                                   |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| 201 Created     | {“message”: “Publish request received.”}                                                                                                                                               | Operation has been scheduled                                          |
| 400 Bad Request | {“error”: {“message”: “ANS invalid: Missing attribute(s) operation”}} {“error”: {“message”: “Improper operation type given (<wrong value>) for expected operations publish\_edition”}} | Missing payload Missing operation type Missing story\_id Missing \_id |

### PUT /unpublish

Schedules an unpublish event

- The values in this table are similar to those in the publish event table; emphasis has been added to these differences.
- You may omit the `date` value from the payload to unpublish the Arc XP content immediately.
- Does not work on Arc XP type `video`.

| Arc type | Payload Field: type                        | Payload Field: operation | Payload Field Name: ans id | Endpoint       |
| -------- | ------------------------------------------ | ------------------------ | -------------------------- | -------------- |
| story    | story\_operation                           | **unpublish\_edition**   | story\_id                  | **/unpublish** |
| gallery  | gallery-operation                          | update                   | \_id                       | **/unpublish** |
| image    | image-operation                            | update                   | \_id                       | **/unpublish** |
| video    | not applicable: videos cannot be scheduled | n/a                      | n/a                        | n/a            |

#### Story Unpublish Operation

Expire a Story. Story will remain in Arc XP but will be changed to an unpublished state on the scheduled date.

```
curl --request PUT \
  --url https://api.<org or sandbox.org>.arcpublishing.com/contentops/v1/unpublish \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "story_operation",
    "story_id": "<ANSID>",
    "operation": "unpublish_edition",
    "date": "YYYY-MM-DDT00:00:00.000000+00:00"
}'
```

#### Image or Gallery Unpublish Operation

Expire an Image or Gallery on the scheduled date. Read [Wire photos and expiration](https://dev.arcxp.com/photo-center/developer-docs/photo-center-wire-photos-and-expiration/) for more information on how photo center treats expiring images or galleries that have been referenced in other published content.

A better way to expire images and galleries is to construct the image ANS or gallery ANS using an expiration date in the field `additional_properties.expiration_date`. This way requires no separate call to an Arc XP API. Photo Center will act on the existence of a date in this ANS field and cause the appropriate action.

```
curl --request PUT \
  --url https://api.<org or sandbox.org>.arcpublishing.com/contentops/v1/unpublish \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "<image or gallery>-operation",
    "_id": "<ANSID>",
    "operation": "update",
    "date": "YYYY-MM-DDT00:00:00.000000+00:00"
}'
```

#### Operations API Responses

| Status Code     | Response Payload                                                                                                                                                                       | Reason for Response                                                   |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| 201 Created     | {“message”: “Unublish request received.”}                                                                                                                                              | Operation has been scheduled                                          |
| 400 Bad Request | {“error”: {“message”: “ANS invalid: Missing attribute(s) operation”}} {“error”: {“message”: “Improper operation type given (<wrong value>) for expected operations publish\_edition”}} | Missing payload Missing operation type Missing story\_id Missing \_id |

### PUT /unschedule\_publish

Cancels a scheduled publish event

- Omit the `date` value from the payload. The future scheduled publish event will be removed as soon as the request is received.
- This endpoint is for correcting the scheduling of future publish events made while running a script. It is not meant to be integrated into daily or heavily used systems operations.

| Arc type | Payload Field: type                        | Payload Field: operation | Payload Field Name: ans id | Endpoint                 |
| -------- | ------------------------------------------ | ------------------------ | -------------------------- | ------------------------ |
| story    | \-                                         | \-                       | story\_id                  | **/unschedule\_publish** |
| gallery  | gallery-operation                          | \-                       | \_id                       | **/unschedule\_publish** |
| image    | image-operation                            | \-                       | \_id                       | **/unschedule\_publish** |
| video    | not applicable: videos cannot be scheduled | n/a                      | n/a                        | n/a                      |

#### Cancel a Publish Story Operation

```
curl --request PUT \
  --url https://api.<org or sandbox.org>.arcpublishing.com/contentops/v1/unschedule_publish \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "story_id": "<ANSID>"
}'
```

#### Cancel a Publish Image or Gallery Operation

```
curl --request PUT \
  --url 'https://api.<org or sandbox.org>.arcpublishing.com/contentops/v1/unschedule_publish' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "<image or gallery>-operation",
    "_id": "<ANSID>"
}'
```

#### Operations API Responses

| Status Code     | Response Payload                                                                                                                                                                            | Reason for Response                                                            |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| 201 Created     | {“message”: “Publish unschedule request received.”}                                                                                                                                         | Operation has been scheduled                                                   |
| 400 Bad Request | {“error”: {“message”: “Missing request parameter(s) story\_id”}} {“error”: {“message”: “ANS invalid: Missing attribute(s) \_id”}} {“error”: {“message”: “Unsupported ANS operation: None”}} | Missing payload Missing story\_id Missing \_id Missing type (image or gallery) |

### PUT /unschedule\_unpublish

Cancels a scheduled unpublish event

- Omit the `date` value from the payload. The future scheduled unpublish event will be removed as soon as the request is received.
- This endpoint is for correcting the scheduling of future publish events made while running a script. It is not meant to be integrated into daily or heavily used systems operations.

| Arc type | Payload Field: type                        | Payload Field: operation | Payload Field Name: ans id | Endpoint                   |
| -------- | ------------------------------------------ | ------------------------ | -------------------------- | -------------------------- |
| story    | \-                                         | \-                       | story\_id                  | **/unschedule\_unpublish** |
| gallery  | gallery-operation                          | \-                       | \_id                       | **/unschedule\_unpublish** |
| image    | image-operation                            | \-                       | \_id                       | **/unschedule\_unpublish** |
| video    | not applicable: videos cannot be scheduled | n/a                      | n/a                        | n/a                        |

#### Cancel a Story Unpublish Operation

```
curl --request PUT \
  --url https://api.<org or sandbox.org>.arcpublishing.com/contentops/v1/unschedule_publish \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "story_id": "<ANSID>"
}'
```

#### Cancel an Image or Gallery Unpublish Operation

```
curl --request PUT \
  --url 'https://api.<org or sandbox.org>.arcpublishing.com/contentops/v1/unschedule_unpublish' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "<image or gallery>-operation",
    "_id": "<ANSID>"
}'
```

#### Operations API Responses

| Status Code     | Response Payload                                                                                                                                                                            | Reason for Response                                                            |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| 201 Created     | {“message”: “Unpublish unschedule request received.”}                                                                                                                                       | Operation has been scheduled                                                   |
| 400 Bad Request | {“error”: {“message”: “Missing request parameter(s) story\_id”}} {“error”: {“message”: “ANS invalid: Missing attribute(s) \_id”}} {“error”: {“message”: “Unsupported ANS operation: None”}} | Missing payload Missing story\_id Missing \_id Missing type (image or gallery) |

### PUT /delete

Schedules a delete event

- The values in this table are similar to those in the publish event table; emphasis has been added to these differences.

| Arc type | Payload Field: type                        | Payload Field: operation | Payload Field Name: ans id | Endpoint    |
| -------- | ------------------------------------------ | ------------------------ | -------------------------- | ----------- |
| story    | story\_operation                           | **delete**               | story\_id                  | **/delete** |
| gallery  | gallery-operation                          | **delete**               | \_id                       | **/delete** |
| image    | image-operation                            | **delete**               | \_id                       | **/delete** |
| video    | not applicable: videos cannot be scheduled | n/a                      | n/a                        | n/a         |

#### Story Delete Operation

Delete a Story. Story will be deleted from Arc XP on the scheduled date. This is not reversible.

```
curl --request PUT \
  --url https://api.<org or sandbox.org>.arcpublishing.com/contentops/v1/unpublish \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "story_operation",
    "story_id": "<ANSID>",
    "operation": "unpublish_edition",
    "date": "YYYY-MM-DDT00:00:00.000000+00:00"
}'
```

#### Image or Gallery Delete Operation

Delete an Image or Gallery. Content will be deleted from Arc XP on the scheduled date. Images contained within a gallery must be deleted individually. Deleting the gallery does not recursively delete the images within.

A better way to delete images and galleries is to construct the image ANS or gallery ANS using an expiration date in the field additional\_properties.expiration\_date. This way requires no separate call to an Arc XP API. Photo Center will act on the existence of a date in this ANS field and cause the appropriate action. For more information, see [Wire photos and expiration](https://dev.arcxp.com/photo-center/developer-docs/photo-center-wire-photos-and-expiration/).

```
curl --request PUT \
  --url https://api.<org or sandbox.org>.arcpublishing.com/contentops/v1/unpublish \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "<image or gallery>-operation",
    "_id": "<ANSID>",
    "operation": "delete",
    "date": "YYYY-MM-DDT00:00:00.000000+00:00"
}'
```

#### Operations API Responses

| Status Code     | Response Payload                                                                                                                                                                       | Reason for Response                                                   |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| 201 Created     | {“message”: “Delete request received.”}                                                                                                                                                | Operation has been scheduled                                          |
| 400 Bad Request | {“error”: {“message”: “ANS invalid: Missing attribute(s) operation”}} {“error”: {“message”: “Improper operation type given (<wrong value>) for expected operations publish\_edition”}} | Missing payload Missing operation type Missing story\_id Missing \_id |

## GET /get\_scheduled

Check if a story, image or gallery has been scheduled for deletion.

- The values in this table are similar to those in the publish event table; emphasis has been added to these differences.

| Arc type | Query Parameter | Endpoint            |
| -------- | --------------- | ------------------- |
| story    | story\_id       | **/get\_scheduled** |
| gallery  | \_id            | **/get\_scheduled** |
| image    | \_id            | **/get\_scheduled** |
| video    | n/a             | n/a                 |

```
curl --request GET \
  --url 'https://api.<org or sandbox.org>.arcpublishing.com/contentops/v1/get_scheduled?story_id=<ANSID>' \
  --header 'Authorization: Bearer <token>'
```

### Operations Responses

This is the response from the API when there are no scheduled operations for the requested story.

```
{
    "content_ref": {
        "operation_type": "story_operation",
        "id": "GNEQVIBN7WMU4T5246VZH4MHDU",
  "ans_object": {
      "story_id": "GNEQVIBN7WMU4T5246VZH4MHDU",
      "type": "story_operation"
  }
    },
    "schedule": []
}
```

This is the response from the API when there are multiple scheduled operations for the requested story.

```
{
  "content_ref": {
    "ans_object": {
      "story_id": "GNEQVIBN7WMU4T5246VZH4MHDU",
      "type": "story_operation"
    },
    "id": "GNEQVIBN7WMU4T5246VZH4MHDU",
    "operation_type": "story_operation"
  },
  "schedule": [
    {
      "date": "2020-09-11T00:00:00+00:00",
      "job_type": "publish"
    },
    {
      "date": "2020-09-13T00:00:00+00:00",
      "job_type": "unpublish"
    },
    {
      "date": "2021-09-30T00:00:00+00:00",
      "job_type": "delete"
    }
  ]
```

## FAQ

### Is it better to use Content Operations to publish /unpublish an image, or to use the additional\_properties fields that direct Photo Center to do the same thing?

It is better to use the additional\_properties fields that let Photo Center handle the future publish and future unpublish events on an image. For more information, see [Wire photos and expiration](https://dev.arcxp.com/photo-center/developer-docs/photo-center-wire-photos-and-expiration/).

### Why can’t I schedule a video to publish or unpublish in the future?

The Content Operations API does not support video. The only supported types are `story`, `image`, and `gallery`.

### Are there additional\_properties fields in ANS that can be used to control the future publish or unpublish dates of a story?

No, the Content Operations API is the only way to update the scheduled publishing or unpublishing dates of a story.

### Can I send Content Operations when I’m using the Migration Center API?

Yes. When using the Migration Center API, use the operations property, which is an array of operations objects. You will need to add additional keys to each operations object: the organization id and the operations endpoint. Otherwise, the contents consist of the same data that is submitted to the Content Operations API.

```
{
    "ANS": { ... },
    "operations": [
        {
            "type": "story_operation",
            "story_id": "<ANSID>",
            "operation": "delete",
            "date": "YYYY-MM-DDTHH:MM:00Z",
            "organization_id": "<org or sandbox.org>",
            "endpoint": "/delete"
        }
    ]
}
```
