# Storefront GraphQL

> The shop front as a graph: the endpoint, the credentials it takes, an example, and every type.

Source: https://storeware.ai/docs/api-reference/storefront-graphql

The storefront graph is what a shopper sees: published products with live prices and stock, collections, and the shop itself. Drafts and archived products are never reachable.

## Endpoint

```http
POST https://api.storeware.ai/graphql/storefront
Authorization: Bearer <credential>
Content-Type: application/json
```

One path for every shop. The credential names the shop, so no shop id is sent. Add `?currency=` with an ISO 4217 code to ask for prices in that currency.

## Credentials

| Credential | Prefix | What it may send |
| --- | --- | --- |
| An agent key. See [How an agent signs in](https://storeware.ai/docs/agents/agent-auth) for the ways to get one. | `swa_` | Any query. |
| A shop's publishable token, which its shop front puts in its pages | `swp_` | Only a document the server already holds, by id. See [Documents a publishable token may run](#documents-a-publishable-token-may-run). |

A merchant's own credentials, an app's access token and a developer token are answered 404 here. This graph is for shoppers and the agents that shop for them; an app reads a shop through the [REST API](https://storeware.ai/docs/api-reference).

## An example

```bash
curl https://api.storeware.ai/graphql/storefront \
  -H "Authorization: Bearer swa_..." \
  -H "Content-Type: application/json" \
  -d '{"query":"query FirstProducts { shop { products(first: 5) { edges { node { handle title inStock fromPrice { amount currency } } } pageInfo { hasNextPage endCursor } } } }"}'
```

```graphql
query FirstProducts {
  shop {
    products(first: 5) {
      edges {
        node {
          handle
          title
          inStock
          fromPrice { amount currency }
        }
      }
      pageInfo { hasNextPage endCursor }
    }
  }
}
```

Money is a [`Money`](https://storeware.ai/docs/api-reference/storefront-graphql/objects#money) object: an amount in the minor unit of its currency, as a string, beside the currency code.

The graph has no mutations. A basket and a checkout go through the agent protocols: see [UCP and ACP](https://storeware.ai/docs/agents/ucp-acp).

## Documents a publishable token may run

A publishable token is public, so it does not send a query. It names one of the documents below by id, either as `documentId` or as `extensions.persistedQuery.sha256Hash`, with its variables. Any other id is refused with `persisted_document_not_found`, and a raw query with `persisted_document_required`.

| Operation | Variables | `documentId` |
| --- | --- | --- |
| `StorefrontProductList` | `$after`, `$collection` | `753710015ed535ba1142b6a8a802284c4fa7a0298eccc027f61a04ec249a18ef` |
| `StorefrontProduct` | `$handle` | `8f6086553f071df118cf94ba3882c6b0ce48259254a1690472a1e760caa24ec0` |
| `StorefrontCollections` | None | `24e42ac4168f7489221c69e4c9a774f51d0171158bc9ec8d0a74dea1b6889726` |
| `StorefrontProductWithCustomData` | `$handle`, `$keys` | `87522b26d1e8bb5d91bda7da6847de6db13db6268716d4c5373640fcfd3c88c8` |

```json
{
  "documentId": "8f6086553f071df118cf94ba3882c6b0ce48259254a1690472a1e760caa24ec0",
  "variables": {
    "handle": "linen-apron"
  }
}
```

## Cost and limits

Every document is priced before it runs, and the price is in the answer under `extensions.cost`: `requestedQueryCost`, and a `throttleStatus` with `maximumAvailable`, `currentlyAvailable` and `restoreRate`, the points a second the budget refills at. A publishable token may spend less on one document than an agent key, and is held to shallower documents with fewer aliases.

| Error code | What happened |
| --- | --- |
| `query_too_complex` | This one document costs more than the credential may spend at once. Ask for fewer items per connection, or split it. |
| `rate_limited` | The credential has spent its points for the minute. Wait for the window to roll. |
| `persisted_document_required` | A publishable token sent a query instead of a document id. |
| `persisted_document_not_found` | No document has that id. |

Each error carries `extensions.code` and the `requestId` to quote when you ask for help. Field suggestions are never sent, and the graph cannot be explored in a browser.

## Reference

- [Queries](https://storeware.ai/docs/api-reference/storefront-graphql/queries): what a query can ask for at the root.
- [Objects](https://storeware.ai/docs/api-reference/storefront-graphql/objects): 14 types.
- [Scalars](https://storeware.ai/docs/api-reference/storefront-graphql/scalars): 2 types.
