Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Opal Content API
license:
name: Opal API License
url: https://www.workwithopal.com/api-license
version: '1.0'
description: 'Operations tagged Content across 2 of this provider''s published API definitions: opal-v2-openapi.yml, opal-v3-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://login.ouropal.com
tags:
- name: Content
paths:
/content/v2:
get:
tags:
- Content
operationId: ReadContentsV2
summary: Get a batch of content
security:
- oauth2:
- offline_access
- api_key:
- Session-Token
parameters:
- name: include
in: query
required: false
description: 'A comma separated list of related entities to include.\
NOTE: `brand` and `workspace` are synonyms but this endpoint only accepts the word `brand`.\
NOTE: Only `asset_references` that are directly associated to the post.
'
schema:
type: array
items:
type: string
enum:
- account
- approval_phase_group
- asset_references
- brand
- budget
- delivery_record
- inherited_labels
- label_sets
- labels
- links
- moment
- placement
- post_components
- post_type
- post_options
- post_type_options
- rich_text_document
- service
- stories
style: form
explode: false
- name: expose
in: query
required: false
description: Expose response data that is only provided by request.
schema:
type: object
properties:
html_content:
type: object
description: "For `text_editor` content _only_, exposes the html rendering of the content on each content\nresource under the `html_content` attribute. Note that this does _not_ apply to `document` \ncontent. For all other content types, this attribute will always be `null`. \n\nUse this parameter as: `?expose[html_content]`\n"
- name: filter
in: query
description: 'Filters for limiting the results.
All timestamp filters (`created_at`, `updated_at`, and `scheduled_at`), use syntax `filter[field_name][gt]=2020-01-01T00:00:00-07:00` Timestamps use iso8601 formatting, such as `YYYY-MM-DD` or `YYYY-MM-DDThh:mmTZD`. Timestamps of the form `YYYY-MM-DD` will be converted to `YYY-MM-DDT00:00:00` in the `America/Los_Angeles` timezone.
If no operator is specified, `eq` will be assumed. For example, `filter[created_at]=2020-01-01` is equivalent to `filter[created_at][gteq]=2020-01-01`. `eq` will convert a date to a 24 hour range. Thus `filter[created_at][eq]=2020-01-01` is equivalent to `filter[created_at][gteq]=2020-01-01T00:00:00-08:00&filter[created_at][lteq]=2020-01-02T00:00:00-08:00`.
'
required: false
schema:
type: object
properties:
account_id:
type: array
items:
type: integer
description: 'Comma separated list of account IDs. If included, will only fetch content associated with these accounts.
'
account_ids:
type: array
items:
type: integer
deprecated: true
description: Deprecated in favor of `account_id`.
brand_id:
type: array
description: 'The IDs of the workspaces to which results should be filtered.
"Workspace ID" and "Brand ID" are synonymous.
Comma separated list of IDs. If included, will only fetch resources associated with these brands. If not included, will return resources associated with all brands that the user belongs to. For example, `filter[brand_id]=1` will fetch all resources associated with brand 1, while `filter[brand_id]=1,2,3` will fetch any resources associated with brands 1, 2, or 3.
'
items:
type: integer
brand_ids:
type: array
items:
type: integer
deprecated: true
description: Deprecated in favor of `brand_id`.
created_at:
allOf:
- type: object
properties:
eq:
type: string
description: 'Equal to filter. If no other filter is specified, `eq` will be assumed.
'
gt:
type: string
description: Greater than filter
gteq:
type: string
description: Greater than or equal to filter
lt:
type: string
description: Less than filter
lteq:
type: string
description: Less than or equal to filter
- format: date-time
- description: 'Filter content by created_at time. Uses syntax `filter[created_at][gt]=2020-01-01T00:00:00-07:00`
'
has_budget:
type: boolean
description: 'When true, will only include content that has an associated budget. When false, will exclude content that has an associated budget. Will return all content when not included.
'
includes_private_content:
type: boolean
deprecated: true
description: 'Deprecated; this endpoint should be expected to return any content accessible to the user.
'
default: true
label_id:
type: array
items:
type: integer
description: 'Comma separated list of label IDs. If included, will only fetch content associated with these labels. For example, `filter[label_id]=1` will fetch all content associated with label 1, while `filter[label_id]=1,2,3` will fetch any content associated with labels 1, 2, or 3.
'
label_ids:
type: array
items:
type: integer
deprecated: true
description: Deprecated in favor of `label_id`.
moment_id:
type: array
items:
type: integer
description: 'Comma separated list of moment IDs. If included, will only fetch content associated with these moments. For example, `filter[moment_id]=1` will fetch all content associated with moment 1, while `filter[moment_id]=1,2,3` will fetch any content associated with moments 1, 2, or 3.
'
moment_ids:
type: array
items:
type: integer
deprecated: true
description: Deprecated in favor of `moment_id`.
post_statuses:
type: array
items:
type: string
description: "Note that the following synonyms are also accepted:\n \"pending\" means \"for_approval\"\n \"denied\" means \"needs_revision\"\n"
enum:
- draft
- for_approval
- needs_revision
- approved
post_type_id:
type: array
items:
type: integer
description: 'Comma separated list of post_type IDs. If included, will only fetch content associated with these post types. For example, `filter[post_type_id]=1` will fetch all content associated with post_type 1, while `filter[post_type_id]=1,2,3` will fetch any content associated with post types 1, 2, or 3.
'
publishing_mode:
type: array
items:
type: string
enum:
- automatic
- semi_automatic
- manual
- none
description: 'If included, will only fetch content with the specified publishing modes. For example, `filter[publishing_mode]=automatic,semi_automatic` will fetch all content where publishing mode is either "automatic" or "semi_automatic".
'
scheduled_at:
allOf:
- type: object
properties:
eq:
type: string
description: 'Equal to filter. If no other filter is specified, `eq` will be assumed.
'
gt:
type: string
description: Greater than filter
gteq:
type: string
description: Greater than or equal to filter
lt:
type: string
description: Less than filter
lteq:
type: string
description: Less than or equal to filter
- format: date-time
- description: 'Filter by the content scheduled_at time. Uses syntax `filter[scheduled_at][gt]=2020-01-01T00:00:00-07:00`.
'
scheduled_start_at:
type: string
format: date-time
deprecated: true
description: Deprecated in favor of `filter[scheduled_at][gt]`
scheduled_end_at:
type: string
format: date-time
deprecated: true
description: Deprecated in favor of `filter[scheduled_at][lt]`
search_terms:
type: array
items:
type: string
description: 'A term or list of terms to search content for. Will return content matching the terms. For example, `filter[search_terms]=dog` will return content that matches a search for "dog".
'
service_id:
type: array
items:
type: integer
description: 'Comma separated list of service IDs. If included, will only fetch content associated with these services. For example, `filter[service_id]=1` will fetch all content associated with service 1, while `filter[service_id]=1,2,3` will fetch any content associated with services 1, 2, or 3.
'
service_ids:
type: array
items:
type: integer
deprecated: true
description: Deprecated in favor of `service_id`.
story_id:
type: array
items:
type: integer
description: 'Comma separated list of story IDs. If included, will only fetch content associated with these stories. For example, `filter[story_id]=1` will fetch all content associated with story 1, while `filter[story_id]=1,2,3` will fetch any content associated with stories 1, 2, or 3.
'
story_ids:
type: array
items:
type: integer
deprecated: true
description: Deprecated in favor of `story_id`.
updated_at:
allOf:
- type: object
properties:
eq:
type: string
description: 'Equal to filter. If no other filter is specified, `eq` will be assumed.
'
gt:
type: string
description: Greater than filter
gteq:
type: string
description: Greater than or equal to filter
lt:
type: string
description: Less than filter
lteq:
type: string
description: Less than or equal to filter
- format: date-time
- description: 'Filter content by updated_at time. Uses syntax `filter[updated_at][gt]=2020-01-01T00:00:00-07:00`
'
user_id:
type: array
items:
type: integer
description: 'Comma separated list of user IDs. If included, will only fetch content associated with these user IDs. For example, `filter[user_id]=1` will fetch all content associated with user ID 1, while `filter[user_id]=1,2,3` will fetch any content associated with user IDs 1, 2, or 3.
'
style: deepObject
explode: true
- name: omit_count
in: query
required: false
description: Optionally omit the `count` field from metadata in the response.
schema:
type: boolean
- name: sort
in: query
description: 'Sort by the given property. All of the valid options are enumerated
(i.e. "sort=moment,position" is valid but "sort=position" is not).
'
required: false
schema:
type: string
enum:
- account
- created_at
- moment
- moment,position
- service
- updated_at
- name: page
description: Specify an offset and limit for pagination
in: query
required: false
schema:
type: object
properties:
limit:
type: integer
default: 50
offset:
type: integer
style: deepObject
explode: true
responses:
'200':
description: All content matching the query filters.
content:
application/json:
schema:
type: object
required:
- data
properties:
data:
type: array
items:
title: content
type: object
required:
- id
- type
- attributes
- relationships
- links
additionalProperties: false
properties:
id:
type: string
pattern: ^[0-9]+$
type:
type: string
enum:
- content
attributes:
type: object
required:
- position
- status
- is_published
- was_manually_published
- is_ghost
- is_private
- default_snapshot_url
- live_url
- takedown_scheduled_at
- scheduled_at
- name
- content
- show_code_name
- publishing_mode
- created_at
- updated_at
additionalProperties: false
properties:
name:
type: string
description: The name of the Content.
position:
type:
- integer
- 'null'
description: 'A relativistic position within the parent Moment.
You can sort Content by position to lay them
out in the intended order. Note that these positions are not
indices (1, 2, 3, 4...).
'
status:
type:
- string
- 'null'
description: The workflow status of the Content.
enum:
- draft
- for_approval
- needs_revision
- approved
- null
content_type:
type:
- string
- 'null'
description: The Content Type name of the Content. This attribute is only `null` when the content is private from the currently authenticated user.
content:
type:
- string
- 'null'
description: 'The unstructured content string of the Content.
This is used for Content Types that do not rely on
Post Options to store content/assets of Content.
'
is_published:
type:
- boolean
- 'null'
description: Whether or not the Content has been published.
was_manually_published:
type:
- boolean
- 'null'
description: Whether or not the Content was manually published.
is_ghost:
type: boolean
description: 'Indicates whether the Content is redacted for the requesting user.
'
is_private:
type: boolean
description: 'Indicates whether the Content is set to private.
'
show_code_name:
type: boolean
description: 'If `is_ghost` is true and `show_code_name` is true then the `name`
property is a "code name" for the piece of Content. The user must request
access to the Content to see the proper name.
'
default_snapshot_url:
type:
- string
- 'null'
description: A URL that serves up the default snapshot preview of this Content.
live_url:
type:
- string
- 'null'
description: The live URL to published Content.
scheduled_at:
type:
- string
- 'null'
format: date-time
description: 'An ISO8601 date-time. The date and time when the Content is scheduled to get published. If the Content has not been explicitly scheduled then this date is based on that of the Moment the Content lives within.
'
start_interval:
type:
- string
- 'null'
description: 'An ISO8601 interval, relative to the start of the related Moment''s schedule, representing the explicitly chosen start datetime of the Content. Values are normalized to a seconds-denominated interval (e.g. `PT86400S`). Null when no specific time has been chosen for the Content — in that case `scheduled_at` falls back to the start of the Moment''s schedule.
'
takedown_scheduled_at:
type:
- string
- 'null'
format: date-time
description: 'An ISO8601 date-time. The date and time when the Content is scheduled to get taken down.
'
post_data:
type:
- object
- 'null'
description: 'A hash that can store any metadata associated with the Content.
'
additionalProperties: true
publishing_mode:
type:
- string
- 'null'
description: The way in which the Content will be published.
post_state:
type:
- string
- 'null'
description: The state of the Content in the workflow process.
enum:
- published
- held
- failed
- publishing
- dispatched
- dispatching
- approved
- pending
created_at:
type: string
format: date-time
description: An ISO8601 date-time.
readOnly: true
updated_at:
type: string
format: date-time
description: An ISO8601 date-time.
readOnly: true
service_id:
type: integer
relationships:
type: object
required:
- account
- approval_phase_group
- asset_references
- brand
- budget
- delivery_record
- inherited_labels
- label_sets
- labels
- links
- moment
- placement
- post_components
- post_options
- post_type
- post_type_options
- rich_text_document
- service
- stories
- user
additionalProperties: false
properties:
account:
type: object
required:
- data
additionalProperties: false
properties:
data:
type:
- object
- 'null'
required:
- id
- type
additionalProperties: false
properties:
id:
type: string
type:
type: string
enum:
- account
approval_phase_group:
type: object
required:
- data
additionalProperties: false
properties:
data:
type:
- object
- 'null'
required:
- id
- type
additionalProperties: false
properties:
id:
type: string
type:
type: string
enum:
- phase-groups
asset_references:
type: object
required:
- data
additionalProperties: false
properties:
data:
type: array
items:
type: object
required:
- id
- type
additionalProperties: false
properties:
id:
type: string
type:
type: string
enum:
- asset_reference
brand:
type: object
required:
- data
additionalProperties: false
properties:
data:
type: object
required:
- id
- type
additionalProperties: false
properties:
id:
type: string
type:
type: string
enum:
- brand
budget:
type: object
required:
- data
additionalProperties: false
properties:
data:
type:
- object
- 'null'
required:
- id
- type
additionalProperties: false
properties:
id:
type: string
type:
type: string
enum:
- budget
delivery_record:
type: object
required:
- data
additionalProperties: false
properties:
data:
type:
- object
- 'null'
required:
- id
- type
additionalProperties: false
properties:
id:
type: string
type:
type: string
enum:
- delivery_record
inherited_labels:
allOf:
- type: object
required:
- data
additionalProperties: false
properties:
data:
type: array
items:
type: object
required:
- id
- type
additionalProperties: false
properties:
id:
type: string
type:
type: string
enum:
- label
- description: 'Only inherited labels. See the [Labels Overview](/api/documentation/v2#tag/Labels/Labels-Overview) for information on inheritance.
'
label_sets:
type: object
required:
- data
additionalProperties: false
properties:
data:
type: array
items:
type: object
required:
- id
- type
additionalProperties: false
properties:
id:
type: string
type:
type: string
enum:
- label_set
labels:
allOf:
- type: object
required:
- data
additionalProperties: false
properties:
data:
type: array
items:
type: object
required:
- id
- type
additionalProperties: false
properties:
id:
type: string
type:
type: string
enum:
- label
- description: 'All labels (inherited or explicitly set). See the [Labels Overview](/api/documentation/v2#tag/Labels/Labels-Overview) for information on inheritance.
'
links:
type: object
# --- truncated at 32 KB (521 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/opal/refs/heads/main/openapi/opal-content-api-openapi.yml