Blog Posts

Create, read, update, delete, bulk manage, translate, and subscribe to blog posts through the Store API.

Blog posts contain a title, sanitized HTML content, an author, optional categories and tags, and publishing and SEO settings. Reads require read_blog; writes require write_blog. Setting a non-empty featured_image_id also requires read_files.

Create a post as a draft, publish it, or schedule its publication. author_ref must identify an author in the same store. Category and tag arrays replace the current assignments when supplied; omit them to preserve assignments or send [] to clear them. A JSON null clears an optional field such as excerpt, SEO, the featured image, or publish_at. Omitting the field leaves the stored value. An omitted or empty update slug preserves the current address. POST /blog/posts/{id}/preview returns a short private draft URL; the response is not cacheable.

Large deletions and author reassignments run as jobs. A scheduled post that cannot be published reports schedule_state and a merchant message.

Translate post content through Blog Post translations. Translation calls require the corresponding blog and translation scopes. Metafield definitions are discovered by namespace and key; the dedicated metafield endpoints document their access rules.

Endpoints#

Blog Post limits

GET read_blog

Fetch Blog Post limits and per-field constraints.

Returns the per-field maximum lengths, enum values, and request caps that apply to Blog Post endpoints. max_per_store is this store's plan cap, count is how many exist now, and usage is the localized label.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

List blog posts

GET read_blog

List blog posts for the store.

Returns paginated Blog Posts. total counts matches for the current filters; store_total counts all records in the store and can be compared with the store capacity returned by the limits endpoint. Filter by search, status, author, category, tag, or publication date. Invalid pagination, UUID, and sort parameters are rejected instead of silently defaulted. storefront_url is the canonical absolute URL on the store's primary domain. storefront_path is the domain-independent baseline route; join it to the storefront address you are targeting. Hosted storefront responses apply translated slugs and locale/country prefixes.

Query parameters

Name Type Description
page integer

Page number.

Example: 1
limit integer

Page size, up to list_max_limit from the Blog Post limits.

Example: 20
search string

Search Blog Posts by title or slug.

Example: launch-notes
status string

Filter by status.

Example: published
author_ref uuid

Filter by blog author id.

Example: 44bf70b7-88e2-4770-a30e-d7a1db522499
category_id uuid

Filter by assigned blog category id.

Example: 3a588f80-fd8c-4d46-af1b-00a1c4a7f85a
tag_id uuid

Filter by assigned blog tag id.

Example: 6e8b7dd1-7ad5-453d-8a87-67daf4ca9f93
publication_date_from date

Include posts published or scheduled on or after this store-local date (YYYY-MM-DD).

Example: 2026-02-01
publication_date_to date

Include posts published or scheduled on or before this store-local date (YYYY-MM-DD).

Example: 2026-02-28
sort_by string

Sort field from the Blog Post list contract.

Allowed values
titlestatusauthorcomment_countpublished_atpublish_atcreated_atupdated_at
Example: created_at
sort_direction string

Sort direction from the Blog Post list contract.

Allowed values
ascdesc
Example: desc

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 VALIDATION_LIST_INVALID_PAGE

    Page must be a positive integer.

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Limit must be within the Blog Post contract cap.

  • 400 VALIDATION_LIST_INVALID_SORT_BY

    Sort field is not supported.

  • 400 VALIDATION_LIST_INVALID_SORT_DIRECTION

    Sort direction must be asc or desc.

  • 400 BLOG_POST_SEARCH_TOO_LONG

    Search exceeds the Blog Post contract max length.

  • 400 BLOG_POST_STATUS_FILTER_INVALID

    Status is not one of the allowed values.

  • 400 BLOG_POST_PUBLICATION_DATE_FILTER_INVALID

    Publication dates must use YYYY-MM-DD and form a valid range.

  • 400 STORE_API_INVALID_REQUEST_BODY

    An author id is not a UUID.

  • 400 STORE_API_INVALID_CATEGORY_ID

    Category id is not a UUID.

  • 400 STORE_API_INVALID_TAG_ID

    Tag id is not a UUID.

Search blog posts

GET read_blog

Search blog posts for picker UIs.

Returns lightweight post options. limit is strict and capped by the Blog Post contract.

Query parameters

Name Type Description
q string

Search query.

Example: launch
status string

Filter by status.

Example: published
limit integer

Suggestion count.

Example: 10
offset integer

Result offset.

Example: 0

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Limit must be a positive integer within the picker cap.

  • 400 INVALID_INPUT

    Offset must be zero or greater.

  • 400 BLOG_POST_SEARCH_TOO_LONG

    Search exceeds the Blog Post contract max length.

  • 400 BLOG_POST_STATUS_FILTER_INVALID

    Status is not one of the allowed values.

Get a blog post

GET read_blog

Fetch one blog post by id.

Returns the Blog Post if it belongs to the token's store. storefront_url is the canonical absolute URL on the store's primary domain. storefront_path is the domain-independent baseline route; join it to the storefront address you are targeting. Hosted storefront responses apply translated slugs and locale/country prefixes.

Path parameters

Name Type Description
id required uuid

Blog Post id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 BLOG_POST_IDS_INVALID

    Blog Post id is not a valid UUID.

  • 404 NOT_FOUND

    Blog Post does not exist in this store.

List blog post metafields

GET read_blog

List custom-data values visible to the token.

Definitions are filtered through the token's access rules.

Path parameters

Name Type Description
id required uuid

Blog Post id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Query parameters

Name Type Description
page integer

Page number (default 1).

limit integer

Page size; capped by the metafield list limit.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 VALIDATION_LIST_INVALID_PAGE

    Page must be a positive integer.

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Limit must be a positive integer.

  • 404 NOT_FOUND

    The resource does not exist in this store.

Set blog post metafields

PUT write_blog

Create, update, or delete custom-data values.

Send namespace-and-key entries. A string value creates or replaces a value; null or an empty string deletes it. The complete value change succeeds or fails together. Omitted entries are preserved.

Path parameters

Name Type Description
id required uuid

Blog Post id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
metafields required array<object>

Entries shaped as {namespace, key, value}. value is required in every entry; send null or an empty string to delete the stored value.

Example: [{"namespace":"details","key":"subtitle","value":"Launch"}]

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    The body or entry shape is invalid. Each entry requires an explicit value, including null for deletion.

  • 400 METAFIELD_NO_WRITES

    Provide at least one metafield entry.

  • 400 METAFIELD_DUPLICATE_WRITE

    A namespace and key occur more than once.

  • 400 PRODUCT_METAFIELD_DEF_NOT_FOUND

    The namespace and key do not identify a definition visible to this token. For an app token only its own definitions count: merchant-owned and other apps' definitions return this code.

  • 403 METAFIELD_WRITE_MERCHANT_READ_ONLY

    The definition does not grant value write access.

  • 403 STORE_API_SCOPE_REQUIRED

    Binding a nonempty file_reference or list.file_reference also requires read_files. Clearing a reference does not.

  • 404 NOT_FOUND

    The resource does not exist in this store. A file reference names a file that does not exist in this store.

  • 400 METAFIELD_VALUE_TOO_LONG

    The value exceeds its size limit: the definition's max_value_length, or the platform value size limit for the type.

  • 400 METAFIELD_VALUE_STRING_TOO_LONG

    A string value exceeds the definition's max_value_length or the platform string limit.

  • 400 METAFIELD_VALUE_TOO_SHORT

    A string value is shorter than the definition's min_length rule.

  • 400 METAFIELD_VALUE_PATTERN_MISMATCH

    A string value does not match the definition's pattern rule.

  • 400 METAFIELD_VALUE_INTEGER_INVALID

    An integer value is not a whole number in the 64-bit range.

  • 400 METAFIELD_VALUE_INTEGER_TOO_LONG

    An integer value has more digits than the definition or the platform integer limit allows.

  • 400 METAFIELD_VALUE_DECIMAL_INVALID

    A decimal value is not a finite decimal number.

  • 400 METAFIELD_VALUE_DECIMAL_TOO_LONG

    A decimal value, written out in full, is longer than the definition or the platform decimal limit allows.

  • 400 METAFIELD_VALUE_BELOW_MIN

    An integer or decimal value is below the definition's min rule.

  • 400 METAFIELD_VALUE_ABOVE_MAX

    An integer or decimal value is above the definition's max rule.

  • 400 METAFIELD_VALUE_BOOLEAN_INVALID

    A boolean value is not true or false.

  • 400 METAFIELD_VALUE_DATE_INVALID

    A date value is not a calendar date in YYYY-MM-DD form.

  • 400 METAFIELD_VALUE_DATETIME_INVALID

    A datetime value is not YYYY-MM-DDTHH:mm, YYYY-MM-DDTHH:mm:ss or an RFC 3339 timestamp.

  • 400 METAFIELD_VALUE_JSON_INVALID

    A json value is not valid JSON.

  • 400 METAFIELD_VALUE_JSON_UNSAFE_LINK

    A json value contains a link whose scheme is not http, https, mailto or tel.

  • 400 METAFIELD_VALUE_URL_INVALID

    A url value, or an item of a list.url value, is not an absolute URL with a host.

  • 400 METAFIELD_VALUE_URL_SCHEME

    A url value, or an item of a list.url value, does not use http or https.

  • 400 METAFIELD_VALUE_URL_TOO_LONG

    A url value, or an item of a list.url value, exceeds the definition's max_value_length or the platform URL limit.

  • 400 METAFIELD_VALUE_NOT_IN_CHOICES

    A single_select value is not one of the definition's choice keys.

  • 400 METAFIELD_LIST_CHOICE_INVALID

    An item of a list.single_select value is not one of the definition's choice keys; the message names the item.

  • 400 METAFIELD_LIST_STRINGS_INVALID

    A list.string or list.single_select value is not a JSON array of strings.

  • 400 METAFIELD_LIST_URLS_INVALID

    A list.url value is not a JSON array of strings.

  • 400 METAFIELD_LIST_FILES_INVALID

    A list.file_reference value is not a JSON array of strings.

  • 400 METAFIELD_LIST_IDS_INVALID

    A list.product_reference or list.variant_reference value is not a JSON array of integers.

  • 400 METAFIELD_LIST_EMPTY

    A list value other than list.string is an empty array. Send null or an empty string to remove the value instead.

  • 400 METAFIELD_LIST_TOO_MANY

    A list value has more items than the definition's max_list_items or the platform list limit for the type.

  • 400 METAFIELD_LIST_ITEM_EMPTY

    An item of a list.string value is empty or only whitespace; the message names the item.

  • 400 METAFIELD_LIST_ITEM_TOO_LONG

    An item of a list.string value exceeds the definition's max_value_length or the platform string limit; the message names the item.

  • 400 METAFIELD_VALUE_FILE_UUID_INVALID

    A file_reference value, or an item of a list.file_reference value, is not a file UUID.

  • 400 METAFIELD_VALUE_ID_INVALID

    A product_reference or variant_reference value is not an integer ID.

  • 400 METAFIELD_VALUE_ID_POSITIVE

    A product_reference or variant_reference value is not a positive integer.

  • 400 METAFIELD_VALUE_ID_TOO_LONG

    A product_reference or variant_reference value exceeds the platform reference ID limit.

  • 400 METAFIELD_LIST_ITEMS_POSITIVE

    An item of a list.product_reference or list.variant_reference value is not a positive integer.

  • 400 METAFIELD_REFERENCE_PRODUCT_MISSING

    A product reference names a product that does not exist in this store.

  • 400 METAFIELD_REFERENCE_VARIANT_MISSING

    A variant reference names a variant that does not exist in this store.

  • 400 INVALID_INPUT

    A file reference names a file that is not an uploaded file.

Create a blog post

POST write_blog

Create a blog post.

Creates a Blog Post. title, author_ref, and status are required. author_ref must identify an author in this store. slug is optional on create; when omitted or empty, the backend generates it from the title. storefront_url is the canonical absolute URL on the store's primary domain. storefront_path is the domain-independent baseline route; join it to the storefront address you are targeting. Hosted storefront responses apply translated slugs and locale/country prefixes.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
title required string

Blog Post title.

Example: Launch notes
slug string

Optional slug. Omit to generate from title.

Example: launch-notes
content string

Optional sanitized HTML content.

Example: <p>What changed in this release.</p>
excerpt string

Optional excerpt.

Example: What changed in this release.
featured_image_id string

Optional image file id. Non-empty values must reference an image in this store.

Example: 8f2a1c2b-9d4e-4a56-b789-0123456789ab
author_ref required uuid

Store-scoped blog author id.

Example: 44bf70b7-88e2-4770-a30e-d7a1db522499
seo_title string

Optional SEO title.

Example: Launch notes
seo_description string

Optional SEO description.

Example: Read the latest launch notes.
status required string

Post status: draft, scheduled, published, or archived.

Example: published
publish_at string

Publication time, as a local datetime in the store timezone or RFC 3339 with an offset. Required for scheduled status.

Example: 2026-02-10T09:00:00-05:00
template_handle string

Template assignment. On create, omitting this field or sending an empty string assigns default_blog. Use default_blog for the default Blog Post template, or pass an alternate Blog Post template handle configured for the store. On update, omit template_handle to leave the assignment unchanged, use default_blog to reset it to default, and do not send an empty string.

Example: default_blog
category_ids array<uuid>

Category ids to assign.

Example: ["3a588f80-fd8c-4d46-af1b-00a1c4a7f85a"]
tag_ids array<uuid>

Tag ids to assign.

Example: ["6e8b7dd1-7ad5-453d-8a87-67daf4ca9f93"]

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is malformed or contains an unknown field.

  • 400 BLOG_POST_AUTHOR_REQUIRED

    Author is required.

  • 400 BLOG_POST_TITLE_REQUIRED

    Title is empty after normalization.

  • 400 BLOG_POST_TITLE_TOO_LONG

    Title exceeds the Blog Post contract max length.

  • 400 BLOG_POST_SLUG_FORMAT

    Slug is not valid for Blog Post URLs.

  • 400 BLOG_POST_SLUG_TOO_LONG

    Slug exceeds the Blog Post contract max length.

  • 404 BLOG_AUTHOR_NOT_FOUND

    Author does not exist in this store.

  • 400 BLOG_POST_CONTENT_TOO_LONG

    Content exceeds the Blog Post contract max length.

  • 400 BLOG_POST_EXCERPT_TOO_LONG

    Excerpt exceeds the Blog Post contract max length.

  • 400 BLOG_POST_SEO_TITLE_TOO_LONG

    SEO title exceeds the Blog Post contract max length.

  • 400 BLOG_POST_SEO_DESCRIPTION_TOO_LONG

    SEO description exceeds the Blog Post contract max length.

  • 400 BLOG_POST_STATUS_INVALID

    Status is not one of the allowed values.

  • 400 BLOG_POST_PUBLISH_DATE_REQUIRED

    Scheduled posts require publish_at.

  • 400 BLOG_POST_CATEGORY_IDS_INVALID

    One or more category ids do not exist in this store.

  • 400 BLOG_POST_TAG_IDS_INVALID

    One or more tag ids do not exist in this store.

  • 400 BLOG_POST_CATEGORIES_TOO_MANY

    Category assignments exceed the per-post cap.

  • 400 BLOG_POST_TAGS_TOO_MANY

    Tag assignments exceed the per-post cap.

  • 400 TEMPLATE_HANDLE_INVALID

    Template handle is not valid for Blog Post templates.

  • 400 TEMPLATE_HANDLE_NOT_FOUND

    Template handle does not exist on the store's primary active theme for Blog Post.

  • 409 BLOG_POST_SLUG_DUPLICATE

    Slug already exists in this store.

  • 404 NOT_FOUND

    The featured image does not exist in this store.

  • 400 INVALID_INPUT

    featured_image_id is malformed, is not an image, or belongs to another store.

  • 403 STORE_API_SCOPE_REQUIRED

    A non-empty featured_image_id requires read_files in addition to write_blog.

  • 400 BLOG_POST_PUBLISH_AT_INVALID_FORMAT

    publish_at is not a valid store-local or RFC 3339 datetime.

  • 400 BLOG_POST_SCHEDULED_DATE_PAST

    The supplied schedule is too far in the past.

  • 400 BLOG_POST_LIMIT_REACHED

    The store's blog post limit has been reached.

  • 400 BLOG_POST_PLAN_LIMIT_REACHED

    This store is at its plan blog post cap.

Update a blog post

PUT write_blog

Update a blog post.

Updates provided Blog Post fields. Omitted fields are left unchanged. A blank slug keeps the current slug; a non-empty slug is normalized and validated. Set create_redirect to false to suppress the default redirect when the slug changes. storefront_url is the canonical absolute URL on the store's primary domain. storefront_path is the domain-independent baseline route; join it to the storefront address you are targeting. Hosted storefront responses apply translated slugs and locale/country prefixes.

Path parameters

Name Type Description
id required uuid

Blog Post id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
title string

Blog Post title.

Example: Launch notes
slug string

Optional slug. Omit to generate from title.

Example: launch-notes
content string

Optional sanitized HTML content.

Example: <p>What changed in this release.</p>
excerpt string

Optional excerpt.

Example: What changed in this release.
featured_image_id string

Optional image file id. Non-empty values must reference an image in this store.

Example: 8f2a1c2b-9d4e-4a56-b789-0123456789ab
author_ref uuid

Store-scoped blog author id.

Example: 44bf70b7-88e2-4770-a30e-d7a1db522499
seo_title string

Optional SEO title.

Example: Launch notes
seo_description string

Optional SEO description.

Example: Read the latest launch notes.
status string

Post status: draft, scheduled, published, or archived.

Example: published
publish_at string

Publication time, as a local datetime in the store timezone or RFC 3339 with an offset. Required for scheduled status.

Example: 2026-02-10T09:00:00-05:00
template_handle string

Template assignment. On create, omitting this field or sending an empty string assigns default_blog. Use default_blog for the default Blog Post template, or pass an alternate Blog Post template handle configured for the store. On update, omit template_handle to leave the assignment unchanged, use default_blog to reset it to default, and do not send an empty string.

Example: default_blog
category_ids array<uuid>

Category ids to assign.

Example: ["3a588f80-fd8c-4d46-af1b-00a1c4a7f85a"]
tag_ids array<uuid>

Tag ids to assign.

Example: ["6e8b7dd1-7ad5-453d-8a87-67daf4ca9f93"]
create_redirect boolean

When slug changes, create a redirect from the previous post URL. Defaults to true; set false to suppress it.

Example: true

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is malformed or contains an unknown field.

  • 400 BLOG_POST_AUTHOR_REQUIRED

    Author is required.

  • 400 BLOG_POST_TITLE_REQUIRED

    Title is empty after normalization.

  • 400 BLOG_POST_TITLE_TOO_LONG

    Title exceeds the Blog Post contract max length.

  • 400 BLOG_POST_SLUG_FORMAT

    Slug is not valid for Blog Post URLs.

  • 400 BLOG_POST_SLUG_TOO_LONG

    Slug exceeds the Blog Post contract max length.

  • 404 BLOG_AUTHOR_NOT_FOUND

    Author does not exist in this store.

  • 400 BLOG_POST_CONTENT_TOO_LONG

    Content exceeds the Blog Post contract max length.

  • 400 BLOG_POST_EXCERPT_TOO_LONG

    Excerpt exceeds the Blog Post contract max length.

  • 400 BLOG_POST_SEO_TITLE_TOO_LONG

    SEO title exceeds the Blog Post contract max length.

  • 400 BLOG_POST_SEO_DESCRIPTION_TOO_LONG

    SEO description exceeds the Blog Post contract max length.

  • 400 BLOG_POST_STATUS_INVALID

    Status is not one of the allowed values.

  • 400 BLOG_POST_PUBLISH_DATE_REQUIRED

    Scheduled posts require publish_at.

  • 400 BLOG_POST_CATEGORY_IDS_INVALID

    One or more category ids do not exist in this store.

  • 400 BLOG_POST_TAG_IDS_INVALID

    One or more tag ids do not exist in this store.

  • 400 BLOG_POST_CATEGORIES_TOO_MANY

    Category assignments exceed the per-post cap.

  • 400 BLOG_POST_TAGS_TOO_MANY

    Tag assignments exceed the per-post cap.

  • 400 TEMPLATE_HANDLE_INVALID

    Template handle is not valid for Blog Post templates.

  • 400 TEMPLATE_HANDLE_NOT_FOUND

    Template handle does not exist on the store's primary active theme for Blog Post.

  • 409 BLOG_POST_SLUG_DUPLICATE

    Slug already exists in this store.

  • 404 NOT_FOUND

    The featured image does not exist in this store.

  • 400 INVALID_INPUT

    featured_image_id is malformed, is not an image, or belongs to another store.

  • 403 STORE_API_SCOPE_REQUIRED

    A non-empty featured_image_id requires read_files in addition to write_blog.

  • 400 BLOG_POST_PUBLISH_AT_INVALID_FORMAT

    publish_at is not a valid store-local or RFC 3339 datetime.

  • 400 BLOG_POST_SCHEDULED_DATE_PAST

    The supplied schedule is too far in the past.

  • 409 TRANSLATION_SOURCE_FIELD_HAS_TRANSLATIONS

    Remove translations before clearing their source field.

  • 400 BLOG_POST_IDS_INVALID

    Blog Post id is not a valid UUID.

  • 404 NOT_FOUND

    Blog Post does not exist in this store.

Delete a blog post

DELETE write_blog

Delete a blog post.

Deletes a Blog Post together with its category/tag assignments, comments, and translations. Each cascaded comment emits blog_comments/delete. Menu references require confirmation and are removed after the confirmed delete.

Path parameters

Name Type Description
id required uuid

Blog Post id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
confirmed boolean

Set true only when retrying after CONFIRMATION_REQUIRED.

Example: true
confirmation_token string

Single-use token returned by CONFIRMATION_REQUIRED.

Example: confirm_...

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Blog Post id or delete request body is invalid.

  • 404 NOT_FOUND

    Blog Post does not exist in this store.

  • 400 BLOG_POST_CONFIRMATION_INVALID

    Confirmation token is missing, expired, or does not match this delete.

  • 409 CONFIRMATION_REQUIRED

    Menus reference this post. Review the warnings and retry with the returned token.

Bulk delete blog posts

POST write_blog

Delete multiple blog posts.

Deletes multiple Blog Posts in one request together with their assignments, comments, and translations. Each cascaded comment emits blog_comments/delete. Menu references require confirmation and are removed after the confirmed delete. The request is capped by the Blog Post bulk contract.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
post_ids required array<uuid>

Blog Post ids to delete.

Example: ["5ff7d4ea-3250-4a4d-9d26-07f64d917d31"]
confirmed boolean

Set true only when retrying after CONFIRMATION_REQUIRED.

Example: true
confirmation_token string

Single-use token returned by CONFIRMATION_REQUIRED.

Example: confirm_...

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is malformed, contains unknown fields, or includes a malformed UUID.

  • 400 BLOG_POST_BULK_NO_IDS

    No Blog Post ids were provided.

  • 400 BLOG_POST_BULK_DELETE_TOO_MANY

    Batch exceeds the Blog Post bulk delete cap.

  • 400 BLOG_POST_IDS_INVALID

    One or more post ids do not exist in this store.

  • 400 BLOG_POST_CONFIRMATION_INVALID

    Confirmation token is missing, expired, or does not match the exact selected ids.

  • 409 CONFIRMATION_REQUIRED

    Menus reference one or more selected posts. Review the warnings and retry with the returned token.

Bulk update blog post status

POST write_blog

Update status for multiple blog posts.

Sets draft, published, or archived status on all supplied post ids. Schedule posts individually because this endpoint does not accept a publish date.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
post_ids required array<uuid>

Blog Post ids to update.

Example: ["5ff7d4ea-3250-4a4d-9d26-07f64d917d31"]
status required string

New post status: draft, published, or archived.

Example: published

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is malformed, contains unknown fields, or includes a malformed UUID.

  • 400 BLOG_POST_BULK_NO_IDS

    No Blog Post ids were provided.

  • 400 BLOG_POST_BULK_UPDATE_TOO_MANY

    Batch exceeds the Blog Post bulk update cap.

  • 400 BLOG_POST_IDS_INVALID

    One or more post ids do not exist in this store.

  • 400 BLOG_POST_STATUS_INVALID

    Status must be draft, published, or archived.

  • 400 BLOG_POST_PUBLISH_DATE_REQUIRED

    Scheduled status is not supported by this bulk endpoint.

  • 400 BLOG_POST_AUTHOR_REQUIRED

    A selected post needs an author before it can be published.

Bulk assign categories

POST write_blog

Assign categories to multiple blog posts.

Adds the supplied categories to each post while keeping existing categories.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
post_ids required array<uuid>

Blog Post ids to update.

Example: ["5ff7d4ea-3250-4a4d-9d26-07f64d917d31"]
category_ids required array<uuid>

Category ids to add.

Example: ["3a588f80-fd8c-4d46-af1b-00a1c4a7f85a"]

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is malformed, contains unknown fields, or includes a malformed UUID.

  • 400 BLOG_POST_BULK_NO_IDS

    No Blog Post ids were provided.

  • 400 BLOG_POST_BULK_UPDATE_TOO_MANY

    Batch exceeds the Blog Post bulk update cap.

  • 400 BLOG_POST_IDS_INVALID

    One or more post ids do not exist in this store.

  • 400 STORE_API_INVALID_CATEGORY_ID

    A category id is not a valid UUID.

  • 400 BLOG_POST_CATEGORY_IDS_INVALID

    Category ids are empty or do not exist in this store.

  • 400 BLOG_POST_CATEGORIES_TOO_MANY

    The resulting category set exceeds the per-post cap.

Bulk assign tags

POST write_blog

Assign tags to multiple blog posts.

Adds the supplied tags to each post while keeping existing tags.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
post_ids required array<uuid>

Blog Post ids to update.

Example: ["5ff7d4ea-3250-4a4d-9d26-07f64d917d31"]
tag_ids required array<uuid>

Tag ids to add.

Example: ["6e8b7dd1-7ad5-453d-8a87-67daf4ca9f93"]

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is malformed, contains unknown fields, or includes a malformed UUID.

  • 400 BLOG_POST_BULK_NO_IDS

    No Blog Post ids were provided.

  • 400 BLOG_POST_BULK_UPDATE_TOO_MANY

    Batch exceeds the Blog Post bulk update cap.

  • 400 BLOG_POST_IDS_INVALID

    One or more post ids do not exist in this store.

  • 400 STORE_API_INVALID_TAG_ID

    A tag id is not a valid UUID.

  • 400 BLOG_POST_TAG_IDS_INVALID

    Tag ids are empty or do not exist in this store.

  • 400 BLOG_POST_TAGS_TOO_MANY

    The resulting tag set exceeds the per-post cap.

Bulk remove categories

POST write_blog

Remove categories from multiple blog posts.

Removes the supplied categories from each post while keeping every other category assignment.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
post_ids required array<uuid>

Blog Post ids to update.

Example: ["5ff7d4ea-3250-4a4d-9d26-07f64d917d31"]
category_ids required array<uuid>

Category ids to remove.

Example: ["3a588f80-fd8c-4d46-af1b-00a1c4a7f85a"]

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is malformed, contains unknown fields, or includes a malformed UUID.

  • 400 BLOG_POST_BULK_NO_IDS

    No Blog Post ids were provided.

  • 400 BLOG_POST_BULK_UPDATE_TOO_MANY

    Batch exceeds the Blog Post bulk update cap.

  • 400 BLOG_POST_IDS_INVALID

    One or more post ids do not exist in this store.

  • 400 STORE_API_INVALID_CATEGORY_ID

    A category id is not a valid UUID.

  • 400 BLOG_POST_CATEGORY_IDS_INVALID

    Category ids are empty or do not exist in this store.

Bulk remove tags

POST write_blog

Remove tags from multiple blog posts.

Removes the supplied tags from each post while keeping every other tag assignment.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
post_ids required array<uuid>

Blog Post ids to update.

Example: ["5ff7d4ea-3250-4a4d-9d26-07f64d917d31"]
tag_ids required array<uuid>

Tag ids to remove.

Example: ["6e8b7dd1-7ad5-453d-8a87-67daf4ca9f93"]

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is malformed, contains unknown fields, or includes a malformed UUID.

  • 400 BLOG_POST_BULK_NO_IDS

    No Blog Post ids were provided.

  • 400 BLOG_POST_BULK_UPDATE_TOO_MANY

    Batch exceeds the Blog Post bulk update cap.

  • 400 BLOG_POST_IDS_INVALID

    One or more post ids do not exist in this store.

  • 400 STORE_API_INVALID_TAG_ID

    A tag id is not a valid UUID.

  • 400 BLOG_POST_TAG_IDS_INVALID

    Tag ids are empty or do not exist in this store.

Fields#

Field

Type

Create

Update

Required

Translatable

title

string

Yes

Yes

create

Yes

slug

string

Yes

Yes

Yes

content

string

Yes

Yes

Yes

excerpt

string

Yes

Yes

Yes

featured_image_id

string

Yes

Yes

No

author_ref

string (UUID)

Yes

Yes

create

No

author

string

No

No

No

seo_title

string

Yes

Yes

Yes

seo_description

string

Yes

Yes

Yes

status

string

Yes

Yes

create

No

publish_at

string

Yes

Yes

No

published_at

string (RFC 3339)

No

No

No

template_handle

string

Yes

Yes

No

category_ids

array

Yes

Yes

No

tag_ids

array

Yes

Yes

No

category_count

integer

No

No

No

comment_count

integer

No

No

No

created_at

string (RFC 3339)

No

No

No

updated_at

string (RFC 3339)

No

No

No

storefront_url

url

No

No

No

No

storefront_path

string

No

No

No

No

Webhook events#

Subscribe to these events to keep your integration in sync with blog posts. Each event shows the required Store API scope and store permission, the available payload fields, and an example payload. Subscription setup is validated against those permissions; delivery is always restricted to the subscription's store.

Metafield events are filtered for every subscriber. An app receives events for definitions it owns. With the event's required scope, it also receives merchant-owned definitions and definitions shared by another app through app_access: shared; another app's private definitions are not delivered. A store-level webhook endpoint receives merchant-owned definitions and app-owned definitions unless merchant_access is hidden. If an event cannot identify the definition owner or its access settings, Tringify does not deliver it.

Blog post created

EVENT blog_posts/create App scope: read_blog Staff permission: blog:write

Fired when a blog post is created.

Payload fields

Field Type Description
blog_post.id string Always present
blog_post.title string Selectable in the Payload builder
blog_post.slug string Selectable in the Payload builder
blog_post.content string Selectable in the Payload builder
blog_post.excerpt string Selectable in the Payload builder
blog_post.featured_image_id string Selectable in the Payload builder
blog_post.featured_image_url string Selectable in the Payload builder
blog_post.featured_image_cdn_url string Selectable in the Payload builder
blog_post.author_ref string Selectable in the Payload builder
blog_post.author.id string Always present
blog_post.author.name string Selectable in the Payload builder
blog_post.author.slug string Selectable in the Payload builder
blog_post.author.bio string Selectable in the Payload builder
blog_post.author.avatar_url string Selectable in the Payload builder
blog_post.author.created_at string Selectable in the Payload builder
blog_post.seo_title string Selectable in the Payload builder
blog_post.seo_description string Selectable in the Payload builder
blog_post.template_handle string Selectable in the Payload builder
blog_post.status string Selectable in the Payload builder
blog_post.publish_at string Selectable in the Payload builder
blog_post.published_at string Selectable in the Payload builder
blog_post.comment_count integer Selectable in the Payload builder
blog_post.categories[*].id string Always present
blog_post.categories[*].name string Selectable in the Payload builder
blog_post.categories[*].slug string Selectable in the Payload builder
blog_post.categories[*].description string Selectable in the Payload builder
blog_post.categories[*].seo_title string Selectable in the Payload builder
blog_post.categories[*].seo_description string Selectable in the Payload builder
blog_post.categories[*].template_handle string Selectable in the Payload builder
blog_post.categories[*].post_count integer Selectable in the Payload builder
blog_post.categories[*].created_at string Selectable in the Payload builder
blog_post.categories[*].updated_at string Selectable in the Payload builder
blog_post.tags[*].id string Always present
blog_post.tags[*].name string Selectable in the Payload builder
blog_post.tags[*].slug string Selectable in the Payload builder
blog_post.tags[*].post_count integer Selectable in the Payload builder
blog_post.tags[*].created_at string Selectable in the Payload builder
blog_post.created_at string Selectable in the Payload builder
blog_post.updated_at string Selectable in the Payload builder

Blog post updated

EVENT blog_posts/update App scope: read_blog Staff permission: blog:write

Fired when a blog post is updated.

Possible changed_fields values

The changed_fields array names exactly which of these changed in this event — use it to skip processing updates your integration doesn't care about.

author_ref categories publish_at published_at status tags

Payload fields

Field Type Description
blog_post.id string Always present
blog_post.title string Selectable in the Payload builder
blog_post.slug string Selectable in the Payload builder
blog_post.content string Selectable in the Payload builder

The post's sanitized HTML. Omitted from updates sent by a bulk action, which never changes content; read the post when you need it.

blog_post.excerpt string Selectable in the Payload builder
blog_post.featured_image_id string Selectable in the Payload builder
blog_post.featured_image_url string Selectable in the Payload builder
blog_post.featured_image_cdn_url string Selectable in the Payload builder
blog_post.author_ref string Selectable in the Payload builder
blog_post.author.id string Always present
blog_post.author.name string Selectable in the Payload builder
blog_post.author.slug string Selectable in the Payload builder
blog_post.author.bio string Selectable in the Payload builder
blog_post.author.avatar_url string Selectable in the Payload builder
blog_post.author.created_at string Selectable in the Payload builder
blog_post.seo_title string Selectable in the Payload builder
blog_post.seo_description string Selectable in the Payload builder
blog_post.template_handle string Selectable in the Payload builder
blog_post.status string Selectable in the Payload builder
blog_post.publish_at string Selectable in the Payload builder
blog_post.published_at string Selectable in the Payload builder
blog_post.comment_count integer Selectable in the Payload builder
blog_post.categories[*].id string Always present
blog_post.categories[*].name string Selectable in the Payload builder
blog_post.categories[*].slug string Selectable in the Payload builder
blog_post.categories[*].description string Selectable in the Payload builder
blog_post.categories[*].seo_title string Selectable in the Payload builder
blog_post.categories[*].seo_description string Selectable in the Payload builder
blog_post.categories[*].template_handle string Selectable in the Payload builder
blog_post.categories[*].post_count integer Selectable in the Payload builder
blog_post.categories[*].created_at string Selectable in the Payload builder
blog_post.categories[*].updated_at string Selectable in the Payload builder
blog_post.tags[*].id string Always present
blog_post.tags[*].name string Selectable in the Payload builder
blog_post.tags[*].slug string Selectable in the Payload builder
blog_post.tags[*].post_count integer Selectable in the Payload builder
blog_post.tags[*].created_at string Selectable in the Payload builder
blog_post.created_at string Selectable in the Payload builder
blog_post.updated_at string Selectable in the Payload builder
changed_fields array Selectable in the Payload builder

Present only on updates from a bulk action across several posts: the fields that action changed (status, publish_at and published_at, categories, tags, or author_ref when a deleted author's posts move to another author). These updates leave out blog_post.content.

Blog post deleted

EVENT blog_posts/delete App scope: read_blog Staff permission: blog:write

Fired when a blog post is deleted.

Payload fields

Field Type Description
blog_post.id string Always present
blog_post.title string Selectable in the Payload builder
blog_post.slug string Selectable in the Payload builder

Blog post metafield value created

EVENT blog_post_metafields/create App scope: read_blog Staff permission: blog:write

Fired when a blog post metafield value is created.

Payload fields

Field Type Description
blog_post.id string Always present
blog_post.title string Selectable in the Payload builder
blog_post.slug string Selectable in the Payload builder
metafield.definition.id string Selectable in the Payload builder
metafield.definition.owner_type string Selectable in the Payload builder
metafield.definition.namespace string Selectable in the Payload builder
metafield.definition.key string Selectable in the Payload builder
metafield.definition.name string Selectable in the Payload builder
metafield.definition.description string Selectable in the Payload builder
metafield.definition.type string Selectable in the Payload builder
metafield.definition.is_translatable boolean Selectable in the Payload builder
metafield.definition.max_value_length integer Selectable in the Payload builder
metafield.definition.max_list_items integer Selectable in the Payload builder
metafield.definition.sort_order integer Selectable in the Payload builder
metafield.definition.app_id string Selectable in the Payload builder
metafield.definition.app_access string Selectable in the Payload builder
metafield.definition.merchant_access string Selectable in the Payload builder
metafield.definition.created_at string Selectable in the Payload builder
metafield.definition.updated_at string Selectable in the Payload builder
metafield.definition.usage_count integer Selectable in the Payload builder
metafield.value string Selectable in the Payload builder
metafield.display_value string Selectable in the Payload builder
metafield.display_value_map object Selectable in the Payload builder
metafield.created_at string Selectable in the Payload builder
metafield.updated_at string Selectable in the Payload builder

Blog post metafield value updated

EVENT blog_post_metafields/update App scope: read_blog Staff permission: blog:write

Fired when a blog post metafield value changes.

Possible changed_fields values

The changed_fields array names exactly which of these changed in this event — use it to skip processing updates your integration doesn't care about.

value

Payload fields

Field Type Description
blog_post.id string Always present
blog_post.title string Selectable in the Payload builder
blog_post.slug string Selectable in the Payload builder
previous.definition.id string Selectable in the Payload builder
previous.definition.owner_type string Selectable in the Payload builder
previous.definition.namespace string Selectable in the Payload builder
previous.definition.key string Selectable in the Payload builder
previous.definition.name string Selectable in the Payload builder
previous.definition.description string Selectable in the Payload builder
previous.definition.type string Selectable in the Payload builder
previous.definition.is_translatable boolean Selectable in the Payload builder
previous.definition.max_value_length integer Selectable in the Payload builder
previous.definition.max_list_items integer Selectable in the Payload builder
previous.definition.sort_order integer Selectable in the Payload builder
previous.definition.app_id string Selectable in the Payload builder
previous.definition.app_access string Selectable in the Payload builder
previous.definition.merchant_access string Selectable in the Payload builder
previous.definition.created_at string Selectable in the Payload builder
previous.definition.updated_at string Selectable in the Payload builder
previous.definition.usage_count integer Selectable in the Payload builder
previous.value string Selectable in the Payload builder
previous.display_value string Selectable in the Payload builder
previous.display_value_map object Selectable in the Payload builder
previous.created_at string Selectable in the Payload builder
previous.updated_at string Selectable in the Payload builder
current.definition.id string Selectable in the Payload builder
current.definition.owner_type string Selectable in the Payload builder
current.definition.namespace string Selectable in the Payload builder
current.definition.key string Selectable in the Payload builder
current.definition.name string Selectable in the Payload builder
current.definition.description string Selectable in the Payload builder
current.definition.type string Selectable in the Payload builder
current.definition.is_translatable boolean Selectable in the Payload builder
current.definition.max_value_length integer Selectable in the Payload builder
current.definition.max_list_items integer Selectable in the Payload builder
current.definition.sort_order integer Selectable in the Payload builder
current.definition.app_id string Selectable in the Payload builder
current.definition.app_access string Selectable in the Payload builder
current.definition.merchant_access string Selectable in the Payload builder
current.definition.created_at string Selectable in the Payload builder
current.definition.updated_at string Selectable in the Payload builder
current.definition.usage_count integer Selectable in the Payload builder
current.value string Selectable in the Payload builder
current.display_value string Selectable in the Payload builder
current.display_value_map object Selectable in the Payload builder
current.created_at string Selectable in the Payload builder
current.updated_at string Selectable in the Payload builder
changed_fields array Selectable in the Payload builder

Blog post metafield value deleted

EVENT blog_post_metafields/delete App scope: read_blog Staff permission: blog:write

Fired when a blog post metafield value is deleted, including when its blog post is deleted.

Payload fields

Field Type Description
blog_post.id string Always present
blog_post.title string Selectable in the Payload builder
blog_post.slug string Selectable in the Payload builder
metafield.definition.id string Selectable in the Payload builder
metafield.definition.owner_type string Selectable in the Payload builder
metafield.definition.namespace string Selectable in the Payload builder
metafield.definition.key string Selectable in the Payload builder
metafield.definition.name string Selectable in the Payload builder
metafield.definition.description string Selectable in the Payload builder
metafield.definition.type string Selectable in the Payload builder
metafield.definition.is_translatable boolean Selectable in the Payload builder
metafield.definition.max_value_length integer Selectable in the Payload builder
metafield.definition.max_list_items integer Selectable in the Payload builder
metafield.definition.sort_order integer Selectable in the Payload builder
metafield.definition.app_id string Selectable in the Payload builder
metafield.definition.app_access string Selectable in the Payload builder
metafield.definition.merchant_access string Selectable in the Payload builder
metafield.definition.created_at string Selectable in the Payload builder
metafield.definition.updated_at string Selectable in the Payload builder
metafield.definition.usage_count integer Selectable in the Payload builder
metafield.value string Selectable in the Payload builder
metafield.display_value string Selectable in the Payload builder
metafield.display_value_map object Selectable in the Payload builder
metafield.created_at string Selectable in the Payload builder
metafield.updated_at string Selectable in the Payload builder

Blog settings updated

EVENT blog_settings/update App scope: read_blog Staff permission: blog:write

Fired when blog comment settings change.

Payload fields

Field Type Description
settings.comments_mode string Always present
settings.comments_moderation boolean Selectable in the Payload builder
settings.updated_at string Always present