Getting Started

This guide walks you through your first API call against the Brandmachine GraphQL API.

Prerequisites

Before you begin:

  1. A Brandmachine account
  2. An API token (see Authentication)
  3. A tool to make HTTP requests (cURL, Postman, or code)

Your First Query

Let's check what shop your token is bound to.

Using cURL

curl -X POST https://production.api.brandmachine.shop/graphql \
  -H "Authorization: Bearer bm_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query { getShopName }"
  }'

Using JavaScript

async function whoAmI() {
  const response = await fetch('https://production.api.brandmachine.shop/graphql', {
    method: 'POST',
    headers: {
      Authorization: 'Bearer bm_your_token_here',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: `
        query {
          getShopName
        }
      `,
    }),
  });

  const result = await response.json();

  if (result.errors) {
    console.error('GraphQL Errors:', result.errors);
    return;
  }

  console.log('Shop:', result.data.getShopName);
}

whoAmI();

Expected Response

{
  "data": {
    "getShopName": "my-store.myshopify.com"
  }
}

Useful Read Queries

Once you've confirmed auth works, explore the real domain. A few common starting points (see Queries for the full list with arguments and return types):

# List all your library fashion models
query {
  fashionModels {
    id
    name
    gender
  }
}

# List your campaign images
query {
  campaignImages(limit: 10, offset: 0) {
    id
    title
    status
  }
}

# Get all product studios
query {
  getAllProductStudios {
    id
    title
  }
}

# Get the current credit balance and team info
query {
  currentTeam {
    id
    teamDomain
    isPAYG
  }
  creditBalance {
    balanceCents
    currency
  }
}

# Fetch the public PAYG pricelist
query {
  pricelist {
    pricingVersion
    usageType
    chargeCents
    currency
  }
}

The pricelist returns a flat list of PricelistEntry. Each entry has a usageType string. Entries whose usageType ends in Billable (e.g. campaignImageBillable) are release-tier (one-off export fees); the rest are generation-tier (per-click charges). Bucket them client-side using that suffix.

Understanding GraphQL Queries

GraphQL lets you request exactly the fields you need:

query {
  fashionModels {
    id
    name
    gender
    revisions {
      id
      fullPortraitKey
    }
  }
}

Key concepts:

  • Operation type: query (read) or mutation (write).
  • Fields: you choose which fields to return.
  • Nested fields: request related data like revisions within fashionModels.

Mutations

Mutations create, update, or delete data. For example, to top up credits via Stripe Checkout:

mutation {
  createTopUpCheckoutSession(
    amountCents: 5000
    returnUrl: "https://your-app.example.com/billing/return"
  ) {
    sessionId
    url
  }
}

Redirect the user to the returned url; Stripe sends them back to returnUrl afterward.

To toggle a campaign image result as a favorite:

mutation {
  toggleCampaignImageResultFavorite(id: "uuid-here") {
    id
    favorite
  }
}

See Mutations for the full list.

Using Variables

For dynamic queries, use GraphQL variables instead of interpolating strings:

const query = `
  query GetCampaignImage($id: UUID!) {
    campaignImage(id: $id) {
      id
      title
      status
    }
  }
`;

const variables = { id: '6c2a...your-uuid' };

const response = await fetch('https://production.api.brandmachine.shop/graphql', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer bm_your_token_here',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ query, variables }),
});

Error Handling

Always check result.errors before using result.data:

const result = await response.json();

if (result.errors) {
  console.error('GraphQL errors:', result.errors);
  result.errors.forEach((error) => {
    console.error(`- ${error.message}`);
    if (error.extensions?.code) {
      console.error(`  Code: ${error.extensions.code}`);
    }
  });
  return;
}

const data = result.data;

Look out for INSUFFICIENT_CREDITS if you're calling a billable mutation; the user needs to top up before retrying.

Best Practices

Request Only What You Need

GraphQL excels at returning exactly the fields you ask for. Keep payloads tight.

Use Fragments

fragment ModelBasics on FashionModel {
  id
  name
  gender
}

query {
  fashionModels {
    ...ModelBasics
  }
}

Retry on Transient Errors

async function fetchWithRetry(query, variables, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch('https://production.api.brandmachine.shop/graphql', {
        method: 'POST',
        headers: {
          Authorization: 'Bearer bm_your_token_here',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ query, variables }),
      });
      return await response.json();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise((r) => setTimeout(r, 1000 * (i + 1)));
    }
  }
}

Next Steps

  1. Explore Queries: full reference of read operations
  2. Learn Mutations: write operations
  3. Review Types: object types in the schema
  4. Upload Files: REST upload endpoints

Need Help?

Contact support@brandmachine.shop with the request payload and the errors array if something doesn't work.