---
title: "Content API"
source: https://support.storeconnect.com/articles/content-api
type: article
format: markdown
site: StoreConnect Support — product and developer documentation for StoreConnect
site_index: https://storeconnect.com/llms.txt
docs_index: https://support.storeconnect.com/llms.txt
note: Append .md to any page or article URL on this site to get its Markdown form.
---
# Content API

The content API is the set of endpoints an agent or integration uses to read and build a store's catalog and content: products, categories, pages, articles, content blocks, menus, media and themes. The MCP connector calls the same endpoints.

The endpoints sit under `/api/v1/content`. Every write goes onto a draft rather than the live store, as described in [Content staging](content-staging).

## Find the endpoint contract

The store publishes the full endpoint contract as an OpenAPI document:

```text

https://<your-store-domain>/api/v1/openapi.json
```

The document is public and needs no credential, so you can read it before you have a key. Use it for paths, parameters, request bodies and response shapes. This article covers behavior the document does not describe.

:::note
The content API and the OpenAPI document are served at the root of the domain, not under a store path. For a store at `https://shop.example.com/au`, use `https://shop.example.com/api/v1/openapi.json`. The MCP endpoint and the MCP discovery documents are different: they do use the store path. See [Connect an AI agent to your store](connect-an-ai-agent-to-your-store).
:::

## Authenticating

Send one of two credentials as a bearer token:

- **A store credential**, in three colon-separated parts, `org_id:store_sfid:api_token`. The credential names the store, so it reaches that store whichever address it is sent to.
- **An OAuth 2.1 access token**, obtained through the agent sign-in flow. The token is bound to the store it was issued for, and is refused by any other store.

For a store served at a path, an OAuth token is refused on `/api/v1`, because the token is bound to the store path and the API is served at the domain root. Use a store credential for that store, or connect to the store at the root of the domain.

Both credentials carry the scopes of the Salesforce user behind them, taken from the user's **Store Role**. A request that needs a scope the user does not have is refused with a `403`, so a user whose role grants no scopes can authenticate but cannot read or write any content.

For example, to list the first 100 products changed since the start of March:

```text

curl "https://shop.example.com/api/v1/content/products?limit=100&updated_since=2026-03-01T00:00:00Z" \
  -H "Authorization: Bearer 00D5g000004XyZ1EAA:a1B5g00000AbCdEFGH:example-api-token"
```

:::warning
Setting the `api.disable_path_access` store variable refuses authenticated API requests made on the store's own domain, including this API and the MCP endpoint. Do not set it on a store where anyone connects an agent. See [Store variables](store-variables).
:::

## Scopes

Each resource group has a read scope and a write scope, such as `content.read` and `content.write`, so you can give a credential only the access it needs. The authoring scopes are `content.write`, `catalog.write`, `themes.write` and `publish`.

These rules decide who can create, push and discard a draft:

- **A read scope never allows publishing.** A credential that can read content cannot push a draft to Salesforce.
- **Any authoring scope can push a draft the credential owns.**
- **Creating a draft through the REST API needs `content.write`.** Every other REST write names a draft the credential already owns, so a credential with only `catalog.write` cannot start one over REST. Through MCP, the first write opens a draft automatically, so a credential with only `catalog.write` can stage changes and push them.
- **Discarding a draft needs `content.write` through MCP**, or any authoring scope through the REST API.

## Paging through results

Collections are paginated with a cursor rather than an offset. Records change while a draft is being edited, and an offset would skip or repeat rows.

Each response includes a `pagination` object. When `pagination.has_more` is `true`, pass the value of `pagination.cursor` as the `cursor` parameter to fetch the next page. When `has_more` is `false`, you have the last page.

Set the page size with `limit`. The default is 50 and the maximum is 200.

## Fetching only what changed

Pass `updated_since` to a list request to fetch only records changed after a timestamp. Results are ordered by when each record was last changed, then by id, so records that share a timestamp still page in a stable order.

:::warning
`updated_since` must be an ISO 8601 timestamp, such as `2026-03-01T00:00:00Z`. A value that cannot be parsed is ignored, and the full collection is returned instead of the changes.
:::

## Keeping a copy in sync

`updated_since` does not report deleted records. To keep a local copy in sync, including deletions, use the `changes` endpoint for the resource, such as `GET /api/v1/content/products/changes`. Pages, articles, categories, products, menus, themes, media, content blocks and the trait resources each have one. See the OpenAPI document for the exact paths.

1.  Send the first request without a `since` parameter.
2.  Store the `sync_token` from the response. The response also contains the changed records in `data`, and the ids of deleted records in `deleted`.
3.  While `has_more` is `true`, send the request again with `since` set to the latest `sync_token`.
4.  On the next sync, send `since` with the last stored `sync_token`.

A sync token expires 90 days after it is issued. A request with an expired token is refused with a `422`. Start again from step 1.

---

## Follow StoreConnect

- [Email Newsletter](https://storeconnect.com/c/lp-newsletter)
- [LinkedIn Newsletter](https://www.linkedin.com/build-relation/newsletter-follow?entityUrn=7444956928444862464)
- [YouTube](https://www.youtube.com/channel/UCngKdP2x8l1wcbAKW3tvU8g)
- [LinkedIn](https://www.linkedin.com/company/storeconnect)
- [X / Twitter](https://x.com/storeconnecthq)

## Popular Links

- [Partners](https://storeconnect.com/partners)
- [Become a Partner](https://storeconnect.com/become-a-partner)
- [News](https://storeconnect.com/articles/news)
- [Events](https://storeconnect.com/articles/events)
- [Feature Comparison](https://storeconnect.com/how-we-compare)
- [Download a free trial](https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000FMkeKUAT)
- [Book a Demo](https://storeconnect.com/contact)

## Documentation

- [Help documentation](https://support.storeconnect.com/help-documentation)
- [AI agents](https://support.storeconnect.com/ai)
- [Videos & tutorials](https://support.storeconnect.com/videos-tutorials)
- [Developer reference](https://support.storeconnect.com/developer-reference)
- [Release notes](https://support.storeconnect.com/release-notes)
- [Troubleshooting](https://support.storeconnect.com/troubleshooting)
- [Trust Center](https://trust.getstoreconnect.com/)
- [Status Page](https://status.storeconnect.com/)

## Contact

- info@getstoreconnect.com
- US +1 415 745 3230
- AUS +61 2 8365 2308

100 S Ashley Dr, Suite 600-2461
Tampa FL 33602-600 USA

Level 22, Sydney Place
180 George Street
Sydney, NSW, 2000, AUS

## Machine-readable

- [Site index for agents](https://storeconnect.com/llms.txt): curated map of the StoreConnect site in llms.txt format
- [Documentation index for agents](https://support.storeconnect.com/llms.txt): full technical and product documentation map

Every page and article on this site has a Markdown rendering: append `.md` to its URL.

Continue in Markdown: [Help documentation](https://support.storeconnect.com/help-documentation.md) · [Developer reference](https://support.storeconnect.com/developer-reference.md) · [Videos & tutorials](https://support.storeconnect.com/videos-tutorials.md) · [Release notes](https://support.storeconnect.com/release-notes.md)

---

StoreConnect Support — https://support.storeconnect.com/articles/content-api