Skip to main content
This page walks through making your first real request against the Customei API. By the end you’ll have:
  • Called the /api/graphql endpoint with a GraphQL client.
  • Fetched a list of templates from your account.
  • Seen how errors are shaped.
  • Know where to go next for full schema exploration.

Before you start

You need:
  • A Customei-enabled Shopify store you can sign into as Owner or Staff.
  • A session token (or standalone-mode env vars for local dev). See Authentication if you haven’t done this yet.
  • curl or a GraphQL client (we’ll use graphql-request in the Node example, but any client works).

Your first query

Let’s fetch the current shop’s basic info — a safe, read-only query that works for every authenticated caller.

curl

curl -X POST https://your-app.example.com/api/graphql \
  -H 'Authorization: Bearer <your-session-token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "{ shop { id name domain } }"
  }'
Expected response:
{
  "data": {
    "shop": {
      "id": "shop_01H8...",
      "name": "Alex's Custom Mugs",
      "domain": "alexmugs.myshopify.com"
    }
  }
}

Node.js with graphql-request

import { GraphQLClient, gql } from 'graphql-request';

const client = new GraphQLClient('https://your-app.example.com/api/graphql', {
  headers: {
    authorization: `Bearer ${await getSessionToken(app)}`,
  },
});

const query = gql`
  query CurrentShop {
    shop {
      id
      name
      domain
    }
  }
`;

const data = await client.request(query);
console.log(data.shop.name);

Fetch-only (no client library)

const response = await fetch('https://your-app.example.com/api/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${token}`,
  },
  body: JSON.stringify({
    query: '{ shop { id name domain } }',
  }),
});

const { data, errors } = await response.json();
if (errors) throw new Error(errors[0].message);
console.log(data.shop.name);

A slightly more interesting query

Let’s fetch the first ten design templates in the account:
query FirstTemplates {
  designTemplates(limit: 10, offset: 0) {
    items {
      id
      name
      canvasWidth
      canvasHeight
      createdAt
      updatedAt
    }
    totalCount
  }
}
Typical response:
{
  "data": {
    "designTemplates": {
      "items": [
        {
          "id": "tpl_01H8...",
          "name": "Mug - Name + Photo",
          "canvasWidth": 2400,
          "canvasHeight": 1000,
          "createdAt": "2026-02-14T08:23:11.000Z",
          "updatedAt": "2026-04-10T14:08:44.000Z"
        }
      ],
      "totalCount": 42
    }
  }
}
Two things to notice:
  • Pagination uses a limit + offset pair in most list queries. Results come back in a { items, totalCount } wrapper so you can drive pagers from a single query.
  • Filtering is done with a where argument (when supported). For example, designTemplates(where: { name: { contains: "Mug" } }) — see each query’s schema for the exact filter inputs.

A mutation: create a template

Mutations look just like queries, with the mutation keyword:
mutation CreateTemplate($input: DesignTemplateCreateInput!) {
  designTemplateCreate(input: $input) {
    id
    name
    canvasWidth
    canvasHeight
  }
}
Call it with variables:
{
  "query": "mutation CreateTemplate($input: DesignTemplateCreateInput!) { designTemplateCreate(input: $input) { id name } }",
  "variables": {
    "input": {
      "name": "Test from API",
      "canvasWidth": 1000,
      "canvasHeight": 1000
    }
  }
}
If the member whose token you used lacks template:create, Customei responds with a 403 and a permission error. See Errors and rate limits.

Exploring the schema

Customei’s GraphQL Yoga endpoint ships an interactive GraphiQL explorer in development and for authenticated admin sessions in production. Visit https://your-app.example.com/api/graphql in a browser while signed into the embedded admin and you’ll get:
  • A schema browser on the right — click any type to see its fields.
  • A query editor with autocompletion.
  • A response pane that runs against your real account.
Use GraphiQL to prototype queries before wiring them into your code. Copy the final query back to your client verbatim. If GraphiQL is disabled on your deployment, you can also run an introspection query:
{
  __schema {
    queryType { name }
    mutationType { name }
    types {
      name
      kind
    }
  }
}
Most GraphQL client libraries have a getSchema() helper that does this for you.

Query conventions you’ll see throughout the API

A few patterns are worth memorizing — they recur across almost every resource:
  • { items, totalCount } lists. Every list field follows this shape. Drive pagers from totalCount plus limit + offset.
  • where filters. Most lists accept a where argument with equals, in, contains, gte, lte operators per field. Combine with AND / OR.
  • Auto-include for relations. Customei’s Prisma middleware auto-includes related objects based on what you ask for in the query — no manual includeLayers: true flag needed. Just select the nested fields you want and they come back.
  • ID prefixes. Each resource type has a distinctive ID prefix: tpl_ for templates, os_ for option sets, lib_ for libraries, ord_ for orders. Useful for debugging where an ID came from.
  • Timestamps. All dates are ISO-8601 UTC strings.

Next