openapi: 3.1.0 info: title: Storyblok Content Delivery API v2 Assets Stories API description: The Storyblok Content Delivery API v2 is a REST API that enables developers to fetch published content from a Storyblok space for delivery to end users across web, mobile, and other channels. It provides access to stories, datasources, links, tags, and asset metadata through predictable endpoints with token-based authentication. The API supports filtering, pagination, full-text search, and relation resolution, allowing developers to retrieve precisely the content their application needs. It is optimized for performance and available across multiple regional endpoints to minimize latency for global deployments. version: '2' contact: name: Storyblok Support url: https://www.storyblok.com/contact termsOfService: https://www.storyblok.com/legal/terms-of-service servers: - url: https://api.storyblok.com/v2/cdn description: Global Production Server - url: https://api-us.storyblok.com/v2/cdn description: US Production Server - url: https://api-ap.storyblok.com/v2/cdn description: Asia-Pacific Production Server - url: https://api-ca.storyblok.com/v2/cdn description: Canada Production Server - url: https://api-cn.storyblok.com/v2/cdn description: China Production Server security: - apiToken: [] tags: - name: Stories description: Stories are the content entries in Storyblok. Each story is defined by a component schema and holds the content of a page, post, or any other structured content type. paths: /stories: get: operationId: listStories summary: List multiple stories description: Returns a paginated list of published stories from the space. Stories can be filtered by slug, tag, component type, and custom fields. The response includes the story content along with metadata such as publication dates and alternate language versions. Pagination is controlled via the page and per_page query parameters. tags: - Stories parameters: - $ref: '#/components/parameters/Token' - $ref: '#/components/parameters/Version' - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/PerPage' - name: starts_with in: query description: Filter stories by full_slug prefix. Only stories whose full_slug starts with the given value are returned. Useful for fetching content within a specific folder. required: false schema: type: string example: blog/ - name: by_slugs in: query description: Comma-separated list of full_slug values to retrieve specific stories by their slugs. required: false schema: type: string - name: excluding_slugs in: query description: Comma-separated list of full_slug values to exclude from the results. required: false schema: type: string - name: with_tag in: query description: Comma-separated list of tag slugs to filter stories by. Multiple tags are treated as an OR condition. required: false schema: type: string - name: is_startpage in: query description: Set to 1 to only return folder start pages. Set to 0 to exclude them. Omit to return all stories. required: false schema: type: integer enum: - 0 - 1 - name: sort_by in: query description: 'Sort the response by a specific field and direction. Supports all default story fields and custom fields defined in the component schema. Format: field:asc or field:desc.' required: false schema: type: string example: published_at:desc - name: search_term in: query description: Full-text search term to filter stories whose content fields contain the given string. required: false schema: type: string - name: resolve_relations in: query description: Comma-separated list of component.field paths to resolve referenced story relations inline in the response. required: false schema: type: string - name: resolve_links in: query description: Set to story to resolve story link fields. Set to url to resolve to the story URL string. required: false schema: type: string enum: - story - url - name: language in: query description: ISO language code to return the story content in the specified language. Falls back to the default language if the translation is unavailable. required: false schema: type: string example: en - name: fallback_lang in: query description: Fallback language code used when the requested language translation is not available. required: false schema: type: string - name: filter_query in: query description: Object to filter stories by custom field values using operators such as in, not_in, like, gt-int, lt-int. Keys are field paths relative to the story content object. required: false schema: type: object additionalProperties: true - name: by_uuids in: query description: Comma-separated list of story UUIDs to retrieve specific stories by their unique identifiers. required: false schema: type: string - name: excluding_ids in: query description: Comma-separated list of story IDs to exclude from the results. required: false schema: type: string - name: per_page in: query description: Number of stories to return per page. Maximum 100. required: false schema: type: integer minimum: 1 maximum: 100 default: 25 - name: cv in: query description: Cache version timestamp. Pass the current Unix timestamp to bypass CDN caching and retrieve the latest content. required: false schema: type: integer responses: '200': description: A paginated list of stories was returned successfully. headers: Total: description: Total number of stories matching the query. schema: type: integer content: application/json: schema: type: object properties: stories: type: array items: $ref: '#/components/schemas/Story' cv: type: integer description: Cache version value for subsequent requests. rels: type: array description: Resolved relation stories when resolve_relations is used. items: $ref: '#/components/schemas/Story' links: type: array description: Resolved link stories when resolve_links is set to story. items: $ref: '#/components/schemas/Story' '401': $ref: '#/components/responses/Unauthorized' '422': $ref: '#/components/responses/UnprocessableEntity' /stories/{slug}: get: operationId: getStoryBySlug summary: Retrieve a single story by slug description: Returns a single published story identified by its full_slug. The slug is the path of the story within the space, such as home or blog/my-post. The response includes the full story content, metadata, and optionally resolved relations and links. tags: - Stories parameters: - $ref: '#/components/parameters/StorySlug' - $ref: '#/components/parameters/Token' - $ref: '#/components/parameters/Version' - name: resolve_relations in: query description: Comma-separated list of component.field paths to resolve referenced story relations inline in the response. required: false schema: type: string - name: resolve_links in: query description: Set to story to resolve story link fields. Set to url to resolve to the story URL string. required: false schema: type: string enum: - story - url - name: language in: query description: ISO language code to return the story content in the specified language. required: false schema: type: string - name: cv in: query description: Cache version timestamp to bypass CDN caching. required: false schema: type: integer responses: '200': description: The story was returned successfully. content: application/json: schema: type: object properties: story: $ref: '#/components/schemas/Story' cv: type: integer description: Cache version value. rels: type: array description: Resolved relation stories. items: $ref: '#/components/schemas/Story' links: type: array description: Resolved link stories. items: $ref: '#/components/schemas/Story' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /stories/{id}: get: operationId: getStoryById summary: Retrieve a single story by ID description: Returns a single published story identified by its numeric ID. This endpoint is useful when you have a story ID from a relation field and need to retrieve the full story object. tags: - Stories parameters: - $ref: '#/components/parameters/StoryId' - $ref: '#/components/parameters/Token' - $ref: '#/components/parameters/Version' - name: language in: query description: ISO language code to return the story content in. required: false schema: type: string - name: cv in: query description: Cache version timestamp to bypass CDN caching. required: false schema: type: integer responses: '200': description: The story was returned successfully. content: application/json: schema: type: object properties: story: $ref: '#/components/schemas/Story' cv: type: integer description: Cache version value. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /spaces/{space_id}/stories: get: operationId: listManagementStories summary: List stories in a space description: Returns a paginated list of stories in the space. The response includes both published and draft stories. Results can be filtered by folder, publication status, component type, and text search. tags: - Stories parameters: - $ref: '#/components/parameters/SpaceId' - $ref: '#/components/parameters/Page_2' - $ref: '#/components/parameters/PerPage_2' - name: with_tag in: query description: Filter stories that have this tag applied. required: false schema: type: string - name: folder_only in: query description: Set to 1 to only return folder stories. required: false schema: type: integer enum: - 0 - 1 - name: story_only in: query description: Set to 1 to exclude folder stories from the results. required: false schema: type: integer enum: - 0 - 1 - name: by_slugs in: query description: Comma-separated list of full_slug values to filter by. required: false schema: type: string - name: search in: query description: Text search to filter stories by name. required: false schema: type: string - name: sort_by in: query description: Field and direction to sort by, formatted as field:asc or field:desc. required: false schema: type: string - name: starts_with in: query description: Filter stories whose full_slug starts with this prefix. required: false schema: type: string - name: in_trash in: query description: Set to 1 to return only stories in the trash. required: false schema: type: integer enum: - 0 - 1 - name: in_release in: query description: Filter stories belonging to a specific release ID. required: false schema: type: integer responses: '200': description: A paginated list of stories was returned successfully. headers: Total: description: Total number of stories matching the query. schema: type: integer content: application/json: schema: type: object properties: stories: type: array items: $ref: '#/components/schemas/ManagementStory' '401': $ref: '#/components/responses/Unauthorized_2' post: operationId: createStory summary: Create a story description: Creates a new story in the space. The request body must include the story name, slug, and content object. Optionally specify a parent_id to nest the story inside a folder. Stories are created in draft state unless publish is set to 1. tags: - Stories parameters: - $ref: '#/components/parameters/SpaceId' requestBody: required: true content: application/json: schema: type: object required: - story properties: story: $ref: '#/components/schemas/StoryInput' publish: type: integer enum: - 0 - 1 description: Set to 1 to immediately publish the story after creation. responses: '201': description: The story was created successfully. content: application/json: schema: type: object properties: story: $ref: '#/components/schemas/ManagementStory' '401': $ref: '#/components/responses/Unauthorized_2' '422': $ref: '#/components/responses/UnprocessableEntity_2' /spaces/{space_id}/stories/{story_id}: get: operationId: getManagementStory summary: Retrieve a single story description: Returns the full details of a single story by its numeric ID, including draft content, workflow state, locks, and publishing history. tags: - Stories parameters: - $ref: '#/components/parameters/SpaceId' - $ref: '#/components/parameters/StoryId_2' responses: '200': description: The story was returned successfully. content: application/json: schema: type: object properties: story: $ref: '#/components/schemas/ManagementStory' '401': $ref: '#/components/responses/Unauthorized_2' '404': $ref: '#/components/responses/NotFound_2' put: operationId: updateStory summary: Update a story description: Updates an existing story's content, metadata, or settings. Only the fields provided in the request body are updated. Set publish to 1 to publish the story as part of the update. tags: - Stories parameters: - $ref: '#/components/parameters/SpaceId' - $ref: '#/components/parameters/StoryId_2' requestBody: required: true content: application/json: schema: type: object required: - story properties: story: $ref: '#/components/schemas/StoryInput' publish: type: integer enum: - 0 - 1 description: Set to 1 to publish the story as part of this update. responses: '200': description: The story was updated successfully. content: application/json: schema: type: object properties: story: $ref: '#/components/schemas/ManagementStory' '401': $ref: '#/components/responses/Unauthorized_2' '404': $ref: '#/components/responses/NotFound_2' '422': $ref: '#/components/responses/UnprocessableEntity_2' delete: operationId: deleteStory summary: Delete a story description: Permanently deletes a story from the space. This action cannot be undone. Deleting a folder story also deletes all stories nested within it. tags: - Stories parameters: - $ref: '#/components/parameters/SpaceId' - $ref: '#/components/parameters/StoryId_2' responses: '200': description: The story was deleted successfully. '401': $ref: '#/components/responses/Unauthorized_2' '404': $ref: '#/components/responses/NotFound_2' /spaces/{space_id}/stories/{story_id}/publish: get: operationId: publishStory summary: Publish a story description: Publishes the current draft version of a story, making it available via the Content Delivery API with the public token. If the story has a scheduled publication date, this endpoint publishes it immediately regardless of the schedule. tags: - Stories parameters: - $ref: '#/components/parameters/SpaceId' - $ref: '#/components/parameters/StoryId_2' - name: release_id in: query description: Publish the story as part of a specific release rather than immediately to production. required: false schema: type: integer - name: lang in: query description: Language code to publish a specific translation of the story. required: false schema: type: string responses: '200': description: The story was published successfully. content: application/json: schema: type: object properties: story: $ref: '#/components/schemas/ManagementStory' '401': $ref: '#/components/responses/Unauthorized_2' '404': $ref: '#/components/responses/NotFound_2' /spaces/{space_id}/stories/{story_id}/unpublish: get: operationId: unpublishStory summary: Unpublish a story description: Unpublishes a story, removing it from public access via the Content Delivery API. The story's draft content is preserved and can be republished at any time. tags: - Stories parameters: - $ref: '#/components/parameters/SpaceId' - $ref: '#/components/parameters/StoryId_2' responses: '200': description: The story was unpublished successfully. content: application/json: schema: type: object properties: story: $ref: '#/components/schemas/ManagementStory' '401': $ref: '#/components/responses/Unauthorized_2' '404': $ref: '#/components/responses/NotFound_2' components: parameters: Token: name: token in: query description: The API access token for the space. Use the public token to access published content or the preview token to access draft content. required: true schema: type: string example: your-public-token Page_2: name: page in: query description: Page number for paginated results, starting at 1. required: false schema: type: integer minimum: 1 default: 1 SpaceId: name: space_id in: path description: Numeric ID of the Storyblok space. required: true schema: type: integer example: 12345 PerPage: name: per_page in: query description: Number of items to return per page. Maximum is 100 for most endpoints. required: false schema: type: integer minimum: 1 maximum: 100 default: 25 Version: name: version in: query description: Content version to retrieve. Use published to get published content (default) or draft to get the latest saved draft. The draft version requires the preview API token. required: false schema: type: string enum: - published - draft default: published StoryId_2: name: story_id in: path description: Numeric ID of the story. required: true schema: type: integer example: 67890 PerPage_2: name: per_page in: query description: Number of results per page. Maximum 100. required: false schema: type: integer minimum: 1 maximum: 100 default: 25 StoryId: name: id in: path description: The numeric ID of the story. required: true schema: type: integer example: 123456 Page: name: page in: query description: Page number for paginated results. Starts at 1. Requesting a page higher than the last available page returns an empty array. required: false schema: type: integer minimum: 1 default: 1 StorySlug: name: slug in: path description: The full_slug of the story, which is the path within the space such as home or blog/my-post. required: true schema: type: string example: blog/my-first-post schemas: Story: type: object description: A story is a content entry in Storyblok. It holds structured content defined by a component schema and metadata such as dates, slug, and language alternates. properties: id: type: integer description: Unique numeric identifier of the story. uuid: type: string format: uuid description: Universally unique identifier of the story. name: type: string description: Display name of the story as shown in the Storyblok editor. slug: type: string description: URL-safe slug of the story within its parent folder. full_slug: type: string description: Full path of the story including any parent folder slugs, used as the primary URL identifier. content: type: object description: The story content as a nested JSON object. The structure is determined by the component schema assigned to this story. Always includes a component field with the component type name. additionalProperties: true is_startpage: type: boolean description: True if this story is the start page (index) of its parent folder. parent_id: type: integer nullable: true description: Numeric ID of the parent folder story, or null if at root. group_id: type: string format: uuid description: UUID used to group alternate language versions of the same story. first_published_at: type: string format: date-time nullable: true description: ISO 8601 timestamp of when the story was first published. published_at: type: string format: date-time nullable: true description: ISO 8601 timestamp of when the story was most recently published. created_at: type: string format: date-time description: ISO 8601 timestamp of when the story was created. updated_at: type: string format: date-time description: ISO 8601 timestamp of the most recent update. sort_by_date: type: string nullable: true description: Optional date string used for custom date-based sorting. tag_list: type: array description: List of tag slugs attached to this story. items: type: string is_folder: type: boolean description: True if this story is a folder rather than a content entry. default_full_slug: type: string nullable: true description: Default language full_slug when the story has language alternates. translated_slugs: type: array description: Language-specific slug overrides for alternate language versions. items: type: object properties: path: type: string description: Translated slug path. name: type: string nullable: true description: Translated story name. lang: type: string description: Language code for this translation. alternates: type: array description: Metadata about alternate language versions of this story. items: $ref: '#/components/schemas/StoryAlternate' Error: type: object description: Error response returned when an API request fails. properties: error: type: string description: Human-readable error message describing what went wrong. ManagementStory: type: object description: A story as returned by the Management API, including draft content, workflow state, and editorial metadata not available via the Content Delivery API. properties: id: type: integer description: Unique numeric identifier of the story. uuid: type: string format: uuid description: Universally unique identifier of the story. name: type: string description: Display name of the story in the editor. slug: type: string description: URL-safe slug within the parent folder. full_slug: type: string description: Full path including parent folder slugs. content: type: object description: Story content as a nested JSON object defined by the component schema. additionalProperties: true is_folder: type: boolean description: True if this story is a folder. is_startpage: type: boolean description: True if this story is the start page of its folder. parent_id: type: integer nullable: true description: Numeric ID of the parent folder, or null if at root. group_id: type: string format: uuid description: UUID grouping alternate language versions of this story. published: type: boolean description: True if the story currently has a published version. published_at: type: string format: date-time nullable: true description: Timestamp of the most recent publication. first_published_at: type: string format: date-time nullable: true description: Timestamp of the first publication. created_at: type: string format: date-time description: Creation timestamp. updated_at: type: string format: date-time description: Last modification timestamp. tag_list: type: array description: Tag slugs attached to this story. items: type: string pinned: type: boolean description: True if the story is pinned in the editor for quick access. position: type: integer description: Sort position within the parent folder. meta_data: type: object nullable: true description: Custom metadata object attached to the story. additionalProperties: true default_root: type: string nullable: true description: Default component type allowed at the root of this story. is_demo: type: boolean description: True if this is a demo story. StoryAlternate: type: object description: Metadata about an alternate language version of a story. properties: id: type: integer description: Numeric ID of the alternate story. name: type: string description: Name of the alternate story. slug: type: string description: Slug of the alternate story. full_slug: type: string description: Full slug of the alternate story. is_folder: type: boolean description: True if the alternate story is a folder. parent_id: type: integer nullable: true description: Parent ID of the alternate story. StoryInput: type: object description: Input object for creating or updating a story. required: - name - slug - content properties: name: type: string description: Display name of the story shown in the editor. slug: type: string description: URL-safe slug segment within the parent folder. content: type: object description: Story content as a JSON object. Must include a component field with the component type name. additionalProperties: true parent_id: type: integer description: Numeric ID of the parent folder story. is_startpage: type: boolean description: Set to true to mark this story as the folder start page. tag_list: type: array description: Tag slugs to attach to the story. items: type: string pinned: type: boolean description: Set to true to pin the story in the editor. meta_data: type: object description: Custom metadata key-value pairs. additionalProperties: true sort_by_date: type: string description: Optional date string for custom date-based sorting. path: type: string description: Custom URL path override for the story. default_root: type: string description: Default root component type for this story. Error_2: type: object description: Error response returned when an API request fails. properties: error: type: string description: Human-readable message describing the error. responses: Unauthorized: description: The request was not authenticated. Ensure the token query parameter contains a valid public or preview API token for the space. content: application/json: schema: $ref: '#/components/schemas/Error' NotFound: description: The requested story was not found. Check that the slug or ID is correct and that the story is published when using the public token. content: application/json: schema: $ref: '#/components/schemas/Error' NotFound_2: description: The requested resource was not found. content: application/json: schema: $ref: '#/components/schemas/Error_2' UnprocessableEntity_2: description: The request body contained validation errors. Check the error message for details on which fields failed validation. content: application/json: schema: $ref: '#/components/schemas/Error_2' UnprocessableEntity: description: The request parameters were invalid. Check the query parameter values for format errors. content: application/json: schema: $ref: '#/components/schemas/Error' Unauthorized_2: description: Authentication failed. Verify the Authorization header contains a valid personal access token or OAuth token. content: application/json: schema: $ref: '#/components/schemas/Error_2' securitySchemes: apiToken: type: apiKey in: query name: token description: Public API token for accessing published content, or Preview API token for accessing draft and published content. Tokens are scoped to a specific Storyblok space. externalDocs: description: Storyblok Content Delivery API v2 Documentation url: https://www.storyblok.com/docs/api/content-delivery/v2