Cheese Store

v2.0.0

Welcome to the Cheese Store API reference. This is a live example of how you can use Spectacle to generate beautiful static documentation for your APIs.

The Cheese Store API is organized around REST. It uses resource-oriented URLs, standard HTTP methods, and returns JSON responses. All requests are authenticated using an API key or OAuth2 token.

Getting Started

  1. Sign up for a developer account at cheesy.sourcey.com
  2. Generate an API key from your dashboard
  3. Include the key in your requests as X-API-Key header

Rate Limiting

Plan Requests/hour Burst
Free 100 10
Pro 10,000 100
Enterprise Unlimited 1,000

When you exceed the rate limit, the API returns 429 Too Many Requests with a Retry-After header.

Pagination

List endpoints return paginated results. Use cursor and limit query parameters:

{
  "items": [...],
  "nextCursor": "eyJpZCI6NDJ9",
  "hasMore": true
}

Hard cheese gouda say cheese. Ricotta cauliflower cheese cheesecake bocconcini edam bocconcini fromage feta. Who moved my cheese bocconcini cheese and wine cottage cheese cheese on toast who moved my cheese caerphilly stinking bishop. Bocconcini cheesy feet the big cheese macaroni cheese cheesy feet mascarpone.

Terms of Service

Contact: cheesy@sourcey.com

Base URLs
https://cheesy.sourcey.com/v2Production
https://sandbox.cheesy.sourcey.com/v2Sandbox (test data, rate limits relaxed)
http://localhost:3000/v2Local development
Version
2.0.0

Authentication

api_keyapiKey

API key authentication. Include your API key in the `X-API-Key` header. Get your key from the [developer dashboard](http://cheesy.sourcey.com/dashboard).

API Key: X-API-Key in header

cheesy_oauthoauth2

OAuth2 authentication for full API access

implicit

Authorization: https://cheesy.sourcey.com/oauth/authorize

Scopes: read:cheeses — Read cheese data, write:cheeses — Create and update cheeses, read:orders — View order history, write:orders — Place and manage orders

authorizationCode

Authorization: https://cheesy.sourcey.com/oauth/authorize

Token: https://cheesy.sourcey.com/oauth/token

Scopes: read:cheeses — Read cheese data, write:cheeses — Create and update cheeses, read:orders — View order history, write:orders — Place and manage orders

bearer_authhttp

JWT token obtained from the `/customer/login` endpoint

Scheme: bearer (JWT)

Cheese

Cheese endpoints provide access to information and operations relating to the cheeses available in the store.

Cheeses can be filtered by status, tags, and category. Each cheese has a unique ID, name, category, and availability status.

GET/cheeses

List all cheeses

Returns a paginated list of cheeses in the store. Results can be filtered by status and sorted by name or creation date.

The response includes cursor-based pagination. Use the nextCursor value from the response as the cursor parameter in subsequent requests.

cursorstringquery

Pagination cursor from a previous response

limitinteger[1, 100]20query

Maximum number of cheeses to return

statusstringavailablependingsoldquery

Filter by availability status

sortstringname-namecreatedAt-createdAtnamequery

Sort order for results

200OKobject

A paginated list of cheeses

429Too Many Requestsobject

Rate limit exceeded

api_keyapiKey in header

API key authentication. Include your API key in the `X-API-Key` header. Get your key from the [developer dashboard](http://cheesy.sourcey.com/dashboard).

cheesy_oauthoauth2

OAuth2 authentication for full API access

Scopes: read:cheeses

curl -X GET 'https://cheesy.sourcey.com/v2/cheeses'
const response = await fetch('https://cheesy.sourcey.com/v2/cheeses', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://cheesy.sourcey.com/v2/cheeses')
data = response.json()
200OK
{
  "items": [
    {
      "id": 42,
      "name": "Gorgonzola",
      "category": {
        "id": 1,
        "name": "Italian Cheese"
      },
      "photoUrls": [
        "https://wannabechef.com/gorgonzola.jpg"
      ],
      "tags": [
        {
          "id": 1,
          "name": "blue"
        }
      ],
      "status": "available",
      "origin": "Italy",
      "pricePerKg": 28.5,
      "ageMonths": 12,
      "organic": false,
      "createdAt": "2024-01-15T09:30:00Z",
      "updatedAt": "2024-01-15T09:30:00Z"
    }
  ],
  "nextCursor": "string",
  "hasMore": true,
  "total": 0
}
429Too Many Requests
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
Response Headers (200)
HeaderDescriptionType
X-Total-CountTotal number of cheeses matching the filterinteger
LinkPagination links (RFC 8288)string
Response Headers (429)
HeaderDescriptionType
Retry-AfterSeconds to wait before retryinginteger
X-Rate-LimitYour rate limit (requests per hour)integer
X-Rate-Limit-RemainingRemaining requests in the current windowinteger
POST/cheeses

Add a new cheese

Add a new cheese to the store inventory. The cheese name must be unique within its category.

application/jsonrequired

Cheese object to add to the store

namestringrequired
categoryobject
namestring
photoUrlsArray<string>
tagsArray<object>
namestring
statusstringavailablependingsoldavailable
originstring | null
pricePerKgnumber (float)
ageMonthsinteger[0, 120]
organicbooleanfalse
201Createdobject

Cheese created successfully

409Conflictobject

A cheese with this name already exists in the category

422Unprocessable Entityobject

The request body failed validation

cheesy_oauthoauth2

OAuth2 authentication for full API access

Scopes: write:cheeses

curl -X POST 'https://cheesy.sourcey.com/v2/cheeses' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "Gorgonzola",
  "category": {
    "name": "Italian Cheese"
  },
  "status": "available",
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "name": "blue"
    },
    {
      "name": "italian"
    },
    {
      "name": "creamy"
    }
  ]
}'
const response = await fetch('https://cheesy.sourcey.com/v2/cheeses', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "name": "Gorgonzola",
  "category": {
    "name": "Italian Cheese"
  },
  "status": "available",
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "name": "blue"
    },
    {
      "name": "italian"
    },
    {
      "name": "creamy"
    }
  ]
}),
});

const data = await response.json();
import requests

payload = {
  "name": "Gorgonzola",
  "category": {
    "name": "Italian Cheese"
  },
  "status": "available",
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "name": "blue"
    },
    {
      "name": "italian"
    },
    {
      "name": "creamy"
    }
  ]
}

response = requests.post('https://cheesy.sourcey.com/v2/cheeses', json=payload)
data = response.json()
Request Body
{
  "name": "string",
  "category": {
    "name": "string"
  },
  "photoUrls": [
    "https://example.com"
  ],
  "tags": [
    {
      "name": "string"
    }
  ],
  "status": "available",
  "origin": "string",
  "pricePerKg": 0,
  "ageMonths": 0,
  "organic": false
}
201Created
{
  "id": 42,
  "name": "Gorgonzola",
  "category": {
    "id": 1,
    "name": "Italian Cheese"
  },
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "id": 1,
      "name": "blue"
    }
  ],
  "status": "available",
  "origin": "Italy",
  "pricePerKg": 28.5,
  "ageMonths": 12,
  "organic": false,
  "createdAt": "2024-01-15T09:30:00Z",
  "updatedAt": "2024-01-15T09:30:00Z"
}
409Conflict
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
422Unprocessable Entity
{
  "code": 422,
  "type": "Validation error",
  "message": "Your cheese is not mouldy enough",
  "errors": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}
Response Headers (201)
HeaderDescriptionType
LocationURL of the newly created cheesestring (uri)
PUT/cheeses

Update an existing cheese

Replace an existing cheese with updated data. The cheese ID in the body must match an existing cheese.

application/jsonrequired

Cheese object with updated fields

idinteger (int64)required

Unique identifier

namestringrequired

Name of the cheese

categoryobject
idinteger (int64)
namestring
photoUrlsArray<string>

URLs of cheese photos

tagsArray<object>

Classification tags

idinteger (int64)
namestring
statusstringavailablependingsoldrequired

Availability status in the store

originstring | null

Country of origin (null if unknown)

pricePerKgnumber (float)

Price per kilogram in USD

ageMonthsinteger[0, 120]

Aging period in months

organicbooleanfalse

Whether the cheese is certified organic

createdAtstring (date-time)

When the cheese was added to the store

updatedAtstring (date-time)

When the cheese was last updated

200OKobject

Cheese updated successfully

404Not Foundobject

The requested resource was not found

422Unprocessable Entityobject

The request body failed validation

cheesy_oauthoauth2

OAuth2 authentication for full API access

Scopes: write:cheeses

curl -X PUT 'https://cheesy.sourcey.com/v2/cheeses' \
  -H 'Content-Type: application/json' \
  -d '{
  "id": 42,
  "name": "Gorgonzola",
  "category": {
    "id": 1,
    "name": "Italian Cheese"
  },
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "id": 1,
      "name": "blue"
    }
  ],
  "status": "available",
  "origin": "Italy",
  "pricePerKg": 28.5,
  "ageMonths": 12,
  "organic": false,
  "createdAt": "2024-01-15T09:30:00Z",
  "updatedAt": "2024-01-15T09:30:00Z"
}'
const response = await fetch('https://cheesy.sourcey.com/v2/cheeses', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "id": 42,
  "name": "Gorgonzola",
  "category": {
    "id": 1,
    "name": "Italian Cheese"
  },
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "id": 1,
      "name": "blue"
    }
  ],
  "status": "available",
  "origin": "Italy",
  "pricePerKg": 28.5,
  "ageMonths": 12,
  "organic": false,
  "createdAt": "2024-01-15T09:30:00Z",
  "updatedAt": "2024-01-15T09:30:00Z"
}),
});

const data = await response.json();
import requests

payload = {
  "id": 42,
  "name": "Gorgonzola",
  "category": {
    "id": 1,
    "name": "Italian Cheese"
  },
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "id": 1,
      "name": "blue"
    }
  ],
  "status": "available",
  "origin": "Italy",
  "pricePerKg": 28.5,
  "ageMonths": 12,
  "organic": False,
  "createdAt": "2024-01-15T09:30:00Z",
  "updatedAt": "2024-01-15T09:30:00Z"
}

response = requests.put('https://cheesy.sourcey.com/v2/cheeses', json=payload)
data = response.json()
Request Body
{
  "id": 42,
  "name": "Gorgonzola",
  "category": {
    "id": 1,
    "name": "Italian Cheese"
  },
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "id": 1,
      "name": "blue"
    }
  ],
  "status": "available",
  "origin": "Italy",
  "pricePerKg": 28.5,
  "ageMonths": 12,
  "organic": false,
  "createdAt": "2024-01-15T09:30:00Z",
  "updatedAt": "2024-01-15T09:30:00Z"
}
200OK
{
  "id": 42,
  "name": "Gorgonzola",
  "category": {
    "id": 1,
    "name": "Italian Cheese"
  },
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "id": 1,
      "name": "blue"
    }
  ],
  "status": "available",
  "origin": "Italy",
  "pricePerKg": 28.5,
  "ageMonths": 12,
  "organic": false,
  "createdAt": "2024-01-15T09:30:00Z",
  "updatedAt": "2024-01-15T09:30:00Z"
}
404Not Found
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
422Unprocessable Entity
{
  "code": 422,
  "type": "Validation error",
  "message": "Your cheese is not mouldy enough",
  "errors": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}
GET/cheeses/findByStatus

Find cheeses by status

Multiple status values can be provided as comma-separated strings. Returns all cheeses matching any of the given statuses.

statusArray<string>availablependingsoldrequiredquery

Status values to filter by

200OKArray<object>

Matching cheeses

400Bad Requestobject

Invalid status value provided

cheesy_oauthoauth2

OAuth2 authentication for full API access

Scopes: read:cheeses

curl -X GET 'https://cheesy.sourcey.com/v2/cheeses/findByStatus'
const response = await fetch('https://cheesy.sourcey.com/v2/cheeses/findByStatus', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://cheesy.sourcey.com/v2/cheeses/findByStatus')
data = response.json()
200OK
[
  {
    "id": 42,
    "name": "Gorgonzola",
    "category": {
      "id": 1,
      "name": "Italian Cheese"
    },
    "photoUrls": [
      "https://wannabechef.com/gorgonzola.jpg"
    ],
    "tags": [
      {
        "id": 1,
        "name": "blue"
      }
    ],
    "status": "available",
    "origin": "Italy",
    "pricePerKg": 28.5,
    "ageMonths": 12,
    "organic": false,
    "createdAt": "2024-01-15T09:30:00Z",
    "updatedAt": "2024-01-15T09:30:00Z"
  }
]
400Bad Request
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
GET/cheeses/findByTags deprecated

Find cheeses by tags

Multiple tags can be provided as comma-separated strings (e.g. ?tags=blue,italian,aged).

Deprecated: Use GET /cheeses?tags=blue,italian query parameter instead.

tagsArray<string>requiredquery

Tags to filter by

200OKArray<object>

Matching cheeses

400Bad Requestobject

Invalid tag value

cheesy_oauthoauth2

OAuth2 authentication for full API access

Scopes: read:cheeses

curl -X GET 'https://cheesy.sourcey.com/v2/cheeses/findByTags'
const response = await fetch('https://cheesy.sourcey.com/v2/cheeses/findByTags', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://cheesy.sourcey.com/v2/cheeses/findByTags')
data = response.json()
200OK
[
  {
    "id": 42,
    "name": "Gorgonzola",
    "category": {
      "id": 1,
      "name": "Italian Cheese"
    },
    "photoUrls": [
      "https://wannabechef.com/gorgonzola.jpg"
    ],
    "tags": [
      {
        "id": 1,
        "name": "blue"
      }
    ],
    "status": "available",
    "origin": "Italy",
    "pricePerKg": 28.5,
    "ageMonths": 12,
    "organic": false,
    "createdAt": "2024-01-15T09:30:00Z",
    "updatedAt": "2024-01-15T09:30:00Z"
  }
]
400Bad Request
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
GET/cheeses/{cheeseId}

Get cheese by ID

Returns detailed information about a specific cheese, including its category, tags, and current availability status.

cheeseIdinteger (int64)requiredpath

Unique identifier for the cheese

200OKobject

Cheese details

404Not Foundobject

The requested resource was not found

api_keyapiKey in header

API key authentication. Include your API key in the `X-API-Key` header. Get your key from the [developer dashboard](http://cheesy.sourcey.com/dashboard).

curl -X GET 'https://cheesy.sourcey.com/v2/cheeses/{cheeseId}'
const response = await fetch('https://cheesy.sourcey.com/v2/cheeses/{cheeseId}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://cheesy.sourcey.com/v2/cheeses/{cheeseId}')
data = response.json()
200OK
{
  "id": 42,
  "name": "Gorgonzola",
  "category": {
    "id": 1,
    "name": "Italian Cheese"
  },
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "id": 1,
      "name": "blue"
    }
  ],
  "status": "available",
  "origin": "Italy",
  "pricePerKg": 28.5,
  "ageMonths": 12,
  "organic": false,
  "createdAt": "2024-01-15T09:30:00Z",
  "updatedAt": "2024-01-15T09:30:00Z"
}
404Not Found
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
POST/cheeses/{cheeseId}

Update cheese with form data

Updates specific fields of a cheese using form data. Only provided fields are updated.

cheeseIdinteger (int64)requiredpath

Unique identifier for the cheese

namestringquery

Updated name of the cheese

statusstringavailablependingsoldquery

Updated status of the cheese

200OKobject

Cheese updated

404Not Foundobject

The requested resource was not found

422Unprocessable Entityobject

The request body failed validation

cheesy_oauthoauth2

OAuth2 authentication for full API access

Scopes: write:cheeses

curl -X POST 'https://cheesy.sourcey.com/v2/cheeses/{cheeseId}'
const response = await fetch('https://cheesy.sourcey.com/v2/cheeses/{cheeseId}', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://cheesy.sourcey.com/v2/cheeses/{cheeseId}')
data = response.json()
200OK
{
  "id": 42,
  "name": "Gorgonzola",
  "category": {
    "id": 1,
    "name": "Italian Cheese"
  },
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "id": 1,
      "name": "blue"
    }
  ],
  "status": "available",
  "origin": "Italy",
  "pricePerKg": 28.5,
  "ageMonths": 12,
  "organic": false,
  "createdAt": "2024-01-15T09:30:00Z",
  "updatedAt": "2024-01-15T09:30:00Z"
}
404Not Found
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
422Unprocessable Entity
{
  "code": 422,
  "type": "Validation error",
  "message": "Your cheese is not mouldy enough",
  "errors": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}
DELETE/cheeses/{cheeseId}

Delete a cheese

Permanently removes a cheese from the store. This action cannot be undone. Any pending orders for this cheese will be cancelled.

cheeseIdinteger (int64)requiredpath

Unique identifier for the cheese

X-Confirm-Deletebooleanrequiredheader

Must be set to true to confirm deletion

204No Content

Cheese deleted successfully

404Not Foundobject

The requested resource was not found

409Conflictobject

Cheese has active orders and cannot be deleted

cheesy_oauthoauth2

OAuth2 authentication for full API access

Scopes: write:cheeses

curl -X DELETE 'https://cheesy.sourcey.com/v2/cheeses/{cheeseId}'
const response = await fetch('https://cheesy.sourcey.com/v2/cheeses/{cheeseId}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://cheesy.sourcey.com/v2/cheeses/{cheeseId}')
data = response.json()
404Not Found
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
409Conflict
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
POST/cheeses/{cheeseId}/uploadImage

Upload a cheese image

Upload a photo of the cheese. Supports JPEG, PNG, and WebP formats. Maximum file size is 10MB.

multipart/form-datarequired
filestring (binary)required

Image file (JPEG, PNG, or WebP, max 10MB)

captionstring

Optional caption for the image

isPrimarybooleanfalse

Set as the primary display image

cheeseIdinteger (int64)requiredpath

ID of cheese to upload image for

200OKobject

Image uploaded successfully

413Payload Too Largeobject

File too large (max 10MB)

415Unsupported Media Typeobject

Unsupported media type

cheesy_oauthoauth2

OAuth2 authentication for full API access

Scopes: write:cheeses

curl -X POST 'https://cheesy.sourcey.com/v2/cheeses/{cheeseId}/uploadImage' \
  -H 'Content-Type: multipart/form-data' \
  -d '{
  "file": "<binary>",
  "caption": "string",
  "isPrimary": false
}'
const response = await fetch('https://cheesy.sourcey.com/v2/cheeses/{cheeseId}/uploadImage', {
  method: 'POST',
  headers: {
    'Content-Type': 'multipart/form-data',
  },
  body: JSON.stringify({
  "file": "<binary>",
  "caption": "string",
  "isPrimary": false
}),
});

const data = await response.json();
import requests

payload = {
  "file": "<binary>",
  "caption": "string",
  "isPrimary": False
}

response = requests.post('https://cheesy.sourcey.com/v2/cheeses/{cheeseId}/uploadImage', json=payload)
data = response.json()
Request Body
{
  "file": "<binary>",
  "caption": "string",
  "isPrimary": false
}
200OK
{
  "imageUrl": "https://example.com",
  "thumbnailUrl": "https://example.com",
  "size": 0
}
413Payload Too Large
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
415Unsupported Media Type
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}

Store

Store endpoints provide access to cheese store orders and inventory management. Orders track the purchase lifecycle from placement through delivery.

GET/store/inventory

Get store inventory

Returns a map of cheese status codes to quantities, representing the current inventory levels.

200OKobject

Inventory counts by status

api_keyapiKey in header

API key authentication. Include your API key in the `X-API-Key` header. Get your key from the [developer dashboard](http://cheesy.sourcey.com/dashboard).

curl -X GET 'https://cheesy.sourcey.com/v2/store/inventory'
const response = await fetch('https://cheesy.sourcey.com/v2/store/inventory', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://cheesy.sourcey.com/v2/store/inventory')
data = response.json()
200OK
{}
POST/store/order

Place a cheese order

Place an order to purchase cheese from the store. The cheese must be in available status.

Orders are processed asynchronously. Use the returned order ID to check status via GET /store/order/{orderId}.

application/jsonrequired

Order details

itemsArray<object>required
cheeseIdinteger (int64)required
quantityinteger[1, 100]required
shippingAddressobjectrequired
streetstringrequired
citystringrequired
statestring | null
zipCodestring
countrystringrequired

ISO 3166-1 alpha-2 country code

notesstring | null
201Createdobject

Order placed successfully

422Unprocessable Entityobject

The request body failed validation

cheesy_oauthoauth2

OAuth2 authentication for full API access

Scopes: write:orders

curl -X POST 'https://cheesy.sourcey.com/v2/store/order' \
  -H 'Content-Type: application/json' \
  -d '{
  "items": [
    {
      "cheeseId": 42,
      "quantity": 3
    },
    {
      "cheeseId": 17,
      "quantity": 1
    }
  ],
  "shippingAddress": {
    "street": "123 Cheese Lane",
    "city": "Cheddarville",
    "state": "WI",
    "zipCode": "53001",
    "country": "US"
  },
  "notes": "Please wrap each wheel separately"
}'
const response = await fetch('https://cheesy.sourcey.com/v2/store/order', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "items": [
    {
      "cheeseId": 42,
      "quantity": 3
    },
    {
      "cheeseId": 17,
      "quantity": 1
    }
  ],
  "shippingAddress": {
    "street": "123 Cheese Lane",
    "city": "Cheddarville",
    "state": "WI",
    "zipCode": "53001",
    "country": "US"
  },
  "notes": "Please wrap each wheel separately"
}),
});

const data = await response.json();
import requests

payload = {
  "items": [
    {
      "cheeseId": 42,
      "quantity": 3
    },
    {
      "cheeseId": 17,
      "quantity": 1
    }
  ],
  "shippingAddress": {
    "street": "123 Cheese Lane",
    "city": "Cheddarville",
    "state": "WI",
    "zipCode": "53001",
    "country": "US"
  },
  "notes": "Please wrap each wheel separately"
}

response = requests.post('https://cheesy.sourcey.com/v2/store/order', json=payload)
data = response.json()
Request Body
{
  "items": [
    {
      "cheeseId": 0,
      "quantity": 1
    }
  ],
  "shippingAddress": {
    "street": "123 Cheese Lane",
    "city": "Cheddarville",
    "state": "WI",
    "zipCode": "53001",
    "country": "US"
  },
  "notes": "string"
}
201Created
{
  "id": 1001,
  "items": [
    {
      "cheeseId": 42,
      "cheeseName": "Gorgonzola",
      "quantity": 3,
      "pricePerKg": 28.5
    },
    {
      "cheeseId": 17,
      "cheeseName": "Brie",
      "quantity": 1,
      "pricePerKg": 22
    }
  ],
  "shippingAddress": {
    "street": "123 Cheese Lane",
    "city": "Cheddarville",
    "state": "WI",
    "zipCode": "53001",
    "country": "US"
  },
  "status": "placed",
  "notes": "Please wrap each wheel separately",
  "total": 114.5,
  "shipDate": null,
  "createdAt": "2026-03-10T14:30:00Z",
  "updatedAt": "2026-03-10T14:30:00Z"
}
422Unprocessable Entity
{
  "code": 422,
  "type": "Validation error",
  "message": "Your cheese is not mouldy enough",
  "errors": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}
Response Headers (201)
HeaderDescriptionType
LocationURL of the created orderstring (uri)
GET/store/order/{orderId}

Get order by ID

Retrieve details of a specific order. For testing, use order IDs between 1 and 10.

orderIdinteger (int64)requiredpath

ID of the order

200OKobject

Order details

404Not Foundobject

The requested resource was not found

api_keyapiKey in header

API key authentication. Include your API key in the `X-API-Key` header. Get your key from the [developer dashboard](http://cheesy.sourcey.com/dashboard).

curl -X GET 'https://cheesy.sourcey.com/v2/store/order/{orderId}'
const response = await fetch('https://cheesy.sourcey.com/v2/store/order/{orderId}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://cheesy.sourcey.com/v2/store/order/{orderId}')
data = response.json()
200OK
{
  "id": 1001,
  "items": [
    {
      "cheeseId": 42,
      "cheeseName": "Gorgonzola",
      "quantity": 3,
      "pricePerKg": 28.5
    },
    {
      "cheeseId": 17,
      "cheeseName": "Brie",
      "quantity": 1,
      "pricePerKg": 22
    }
  ],
  "shippingAddress": {
    "street": "123 Cheese Lane",
    "city": "Cheddarville",
    "state": "WI",
    "zipCode": "53001",
    "country": "US"
  },
  "status": "placed",
  "notes": "Please wrap each wheel separately",
  "total": 114.5,
  "shipDate": null,
  "createdAt": "2026-03-10T14:30:00Z",
  "updatedAt": "2026-03-10T14:30:00Z"
}
404Not Found
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
DELETE/store/order/{orderId}

Cancel an order

Cancel a pending order. Orders that have already been shipped cannot be cancelled.

orderIdinteger (int64)requiredpath

ID of the order

204No Content

Order cancelled successfully

404Not Foundobject

The requested resource was not found

409Conflictobject

Order has already been shipped

cheesy_oauthoauth2

OAuth2 authentication for full API access

Scopes: write:orders

curl -X DELETE 'https://cheesy.sourcey.com/v2/store/order/{orderId}'
const response = await fetch('https://cheesy.sourcey.com/v2/store/order/{orderId}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://cheesy.sourcey.com/v2/store/order/{orderId}')
data = response.json()
404Not Found
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
409Conflict
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}

Customer

Customer endpoints handle account creation, authentication, and profile management.

Customer accounts support OAuth2 login and API key authentication.

POST/customer

Create a customer account

Register a new customer account. The username and email must be unique.

application/jsonrequired

Customer registration details

usernamestringrequired
firstNamestring
lastNamestring
emailstring (email)required
passwordstring (password)required
phonestring | null
201Createdobject

Customer account created

409Conflictobject

Username or email already exists

422Unprocessable Entityobject

The request body failed validation

curl -X POST 'https://cheesy.sourcey.com/v2/customer' \
  -H 'Content-Type: application/json' \
  -d '{
  "username": "gordo",
  "firstName": "Alotta",
  "lastName": "Cheese",
  "email": "love@cheese.com",
  "password": "secret123!",
  "phone": "+3344556677"
}'
const response = await fetch('https://cheesy.sourcey.com/v2/customer', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "username": "gordo",
  "firstName": "Alotta",
  "lastName": "Cheese",
  "email": "love@cheese.com",
  "password": "secret123!",
  "phone": "+3344556677"
}),
});

const data = await response.json();
import requests

payload = {
  "username": "gordo",
  "firstName": "Alotta",
  "lastName": "Cheese",
  "email": "love@cheese.com",
  "password": "secret123!",
  "phone": "+3344556677"
}

response = requests.post('https://cheesy.sourcey.com/v2/customer', json=payload)
data = response.json()
Request Body
{
  "username": "string",
  "firstName": "string",
  "lastName": "string",
  "email": "user@example.com",
  "password": "********",
  "phone": "string"
}
201Created
{
  "id": 1,
  "username": "gordo",
  "firstName": "Alotta",
  "lastName": "Cheese",
  "email": "love@cheese.com",
  "phone": "+3344556677",
  "customerStatus": "gold",
  "favouriteCheese": {
    "id": 42,
    "name": "Gorgonzola",
    "category": {
      "id": 1,
      "name": "Italian Cheese"
    },
    "photoUrls": [
      "https://wannabechef.com/gorgonzola.jpg"
    ],
    "tags": [
      {
        "id": 1,
        "name": "blue"
      }
    ],
    "status": "available",
    "origin": "Italy",
    "pricePerKg": 28.5,
    "ageMonths": 12,
    "organic": false,
    "createdAt": "2024-01-15T09:30:00Z",
    "updatedAt": "2024-01-15T09:30:00Z"
  },
  "createdAt": "2024-01-15T09:30:00Z"
}
409Conflict
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
422Unprocessable Entity
{
  "code": 422,
  "type": "Validation error",
  "message": "Your cheese is not mouldy enough",
  "errors": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}
POST/customer/createMultiple

Create multiple customers

Create a batch of customer accounts from an array. Each customer is validated independently - partial success is possible.

Returns the created customers and any validation errors:

{
  "created": [...],
  "errors": [
    { "index": 2, "message": "Email already exists" }
  ]
}
application/jsonrequired

Array of customer objects to create

Array<object>
usernamestringrequired
firstNamestring
lastNamestring
emailstring (email)required
passwordstring (password)required
phonestring | null
200OKobject

Batch creation result

422Unprocessable Entityobject

The request body failed validation

curl -X POST 'https://cheesy.sourcey.com/v2/customer/createMultiple' \
  -H 'Content-Type: application/json' \
  -d '[
  {
    "username": "string",
    "firstName": "string",
    "lastName": "string",
    "email": "user@example.com",
    "password": "********",
    "phone": "string"
  }
]'
const response = await fetch('https://cheesy.sourcey.com/v2/customer/createMultiple', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify([
  {
    "username": "string",
    "firstName": "string",
    "lastName": "string",
    "email": "user@example.com",
    "password": "********",
    "phone": "string"
  }
]),
});

const data = await response.json();
import requests

payload = [
  {
    "username": "string",
    "firstName": "string",
    "lastName": "string",
    "email": "user@example.com",
    "password": "********",
    "phone": "string"
  }
]

response = requests.post('https://cheesy.sourcey.com/v2/customer/createMultiple', json=payload)
data = response.json()
Request Body
[
  {
    "username": "string",
    "firstName": "string",
    "lastName": "string",
    "email": "user@example.com",
    "password": "********",
    "phone": "string"
  }
]
200OK
{
  "created": [
    {
      "id": 1,
      "username": "gordo",
      "firstName": "Alotta",
      "lastName": "Cheese",
      "email": "love@cheese.com",
      "phone": "+3344556677",
      "customerStatus": "gold",
      "favouriteCheese": {
        "id": 42,
        "name": "Gorgonzola",
        "category": {
          "id": 1,
          "name": "Italian Cheese"
        },
        "photoUrls": [
          "https://wannabechef.com/gorgonzola.jpg"
        ],
        "tags": [
          {
            "id": 1,
            "name": "blue"
          }
        ],
        "status": "available",
        "origin": "Italy",
        "pricePerKg": 28.5,
        "ageMonths": 12,
        "organic": false,
        "createdAt": "2024-01-15T09:30:00Z",
        "updatedAt": "2024-01-15T09:30:00Z"
      },
      "createdAt": "2024-01-15T09:30:00Z"
    }
  ],
  "errors": [
    {
      "index": 0,
      "message": "string"
    }
  ]
}
422Unprocessable Entity
{
  "code": 422,
  "type": "Validation error",
  "message": "Your cheese is not mouldy enough",
  "errors": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}
POST/customer/login

Customer login

Authenticate a customer and receive a session token. The token expires after 24 hours.

application/jsonrequired
usernamestringrequired

The customer's username

passwordstring (password)required

The customer's password

200OKobject

Login successful

401Unauthorizedobject

Invalid username or password

curl -X POST 'https://cheesy.sourcey.com/v2/customer/login' \
  -H 'Content-Type: application/json' \
  -d '{
  "username": "string",
  "password": "********"
}'
const response = await fetch('https://cheesy.sourcey.com/v2/customer/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "username": "string",
  "password": "********"
}),
});

const data = await response.json();
import requests

payload = {
  "username": "string",
  "password": "********"
}

response = requests.post('https://cheesy.sourcey.com/v2/customer/login', json=payload)
data = response.json()
Request Body
{
  "username": "string",
  "password": "********"
}
200OK
{
  "token": "string",
  "expiresAt": "2024-01-15T09:30:00Z"
}
401Unauthorized
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
Response Headers (200)
HeaderDescriptionType
X-Rate-LimitRequests per hour allowed for this customerinteger (int32)
X-Expires-AfterToken expiration date-time (UTC)string (date-time)
GET/customer/logout

Customer logout

End the current customer session and invalidate the session token.

204No Content

Logout successful

bearer_authhttp (bearer)

JWT token obtained from the `/customer/login` endpoint

curl -X GET 'https://cheesy.sourcey.com/v2/customer/logout'
const response = await fetch('https://cheesy.sourcey.com/v2/customer/logout', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://cheesy.sourcey.com/v2/customer/logout')
data = response.json()
GET/customer/{username}

Get customer by username

Retrieve a customer's profile by their username.

usernamestringrequiredpath

The customer's username

200OKobject

Customer profile

404Not Foundobject

The requested resource was not found

api_keyapiKey in header

API key authentication. Include your API key in the `X-API-Key` header. Get your key from the [developer dashboard](http://cheesy.sourcey.com/dashboard).

bearer_authhttp (bearer)

JWT token obtained from the `/customer/login` endpoint

curl -X GET 'https://cheesy.sourcey.com/v2/customer/{username}'
const response = await fetch('https://cheesy.sourcey.com/v2/customer/{username}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://cheesy.sourcey.com/v2/customer/{username}')
data = response.json()
200OK
{
  "id": 1,
  "username": "gordo",
  "firstName": "Alotta",
  "lastName": "Cheese",
  "email": "love@cheese.com",
  "phone": "+3344556677",
  "customerStatus": "gold",
  "favouriteCheese": {
    "id": 42,
    "name": "Gorgonzola",
    "category": {
      "id": 1,
      "name": "Italian Cheese"
    },
    "photoUrls": [
      "https://wannabechef.com/gorgonzola.jpg"
    ],
    "tags": [
      {
        "id": 1,
        "name": "blue"
      }
    ],
    "status": "available",
    "origin": "Italy",
    "pricePerKg": 28.5,
    "ageMonths": 12,
    "organic": false,
    "createdAt": "2024-01-15T09:30:00Z",
    "updatedAt": "2024-01-15T09:30:00Z"
  },
  "createdAt": "2024-01-15T09:30:00Z"
}
404Not Found
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
PUT/customer/{username}

Update customer profile

Update a customer's profile. Can only be performed by the authenticated customer.

application/jsonrequired

Updated customer fields

usernamestringrequired
firstNamestring
lastNamestring
emailstring (email)required
passwordstring (password)required
phonestring | null
usernamestringrequiredpath

The customer's username

200OKobject

Customer updated

404Not Foundobject

The requested resource was not found

422Unprocessable Entityobject

The request body failed validation

bearer_authhttp (bearer)

JWT token obtained from the `/customer/login` endpoint

curl -X PUT 'https://cheesy.sourcey.com/v2/customer/{username}' \
  -H 'Content-Type: application/json' \
  -d '{
  "username": "string",
  "firstName": "string",
  "lastName": "string",
  "email": "user@example.com",
  "password": "********",
  "phone": "string"
}'
const response = await fetch('https://cheesy.sourcey.com/v2/customer/{username}', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "username": "string",
  "firstName": "string",
  "lastName": "string",
  "email": "user@example.com",
  "password": "********",
  "phone": "string"
}),
});

const data = await response.json();
import requests

payload = {
  "username": "string",
  "firstName": "string",
  "lastName": "string",
  "email": "user@example.com",
  "password": "********",
  "phone": "string"
}

response = requests.put('https://cheesy.sourcey.com/v2/customer/{username}', json=payload)
data = response.json()
Request Body
{
  "username": "string",
  "firstName": "string",
  "lastName": "string",
  "email": "user@example.com",
  "password": "********",
  "phone": "string"
}
200OK
{
  "id": 1,
  "username": "gordo",
  "firstName": "Alotta",
  "lastName": "Cheese",
  "email": "love@cheese.com",
  "phone": "+3344556677",
  "customerStatus": "gold",
  "favouriteCheese": {
    "id": 42,
    "name": "Gorgonzola",
    "category": {
      "id": 1,
      "name": "Italian Cheese"
    },
    "photoUrls": [
      "https://wannabechef.com/gorgonzola.jpg"
    ],
    "tags": [
      {
        "id": 1,
        "name": "blue"
      }
    ],
    "status": "available",
    "origin": "Italy",
    "pricePerKg": 28.5,
    "ageMonths": 12,
    "organic": false,
    "createdAt": "2024-01-15T09:30:00Z",
    "updatedAt": "2024-01-15T09:30:00Z"
  },
  "createdAt": "2024-01-15T09:30:00Z"
}
404Not Found
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}
422Unprocessable Entity
{
  "code": 422,
  "type": "Validation error",
  "message": "Your cheese is not mouldy enough",
  "errors": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}
DELETE/customer/{username}

Delete customer account

Permanently delete a customer account and all associated data. This action cannot be undone.

usernamestringrequiredpath

The customer's username

204No Content

Customer deleted

404Not Foundobject

The requested resource was not found

bearer_authhttp (bearer)

JWT token obtained from the `/customer/login` endpoint

curl -X DELETE 'https://cheesy.sourcey.com/v2/customer/{username}'
const response = await fetch('https://cheesy.sourcey.com/v2/customer/{username}', {
  method: 'DELETE',
});

const data = await response.json();
import requests

response = requests.delete('https://cheesy.sourcey.com/v2/customer/{username}')
data = response.json()
404Not Found
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}

Models

Cheese

object
idinteger (int64)required

Unique identifier

namestringrequired

Name of the cheese

categoryobject
idinteger (int64)
namestring
photoUrlsArray<string>

URLs of cheese photos

tagsArray<object>

Classification tags

idinteger (int64)
namestring
statusstringavailablependingsoldrequired

Availability status in the store

originstring | null

Country of origin (null if unknown)

pricePerKgnumber (float)

Price per kilogram in USD

ageMonthsinteger[0, 120]

Aging period in months

organicbooleanfalse

Whether the cheese is certified organic

createdAtstring (date-time)

When the cheese was added to the store

updatedAtstring (date-time)

When the cheese was last updated

Example
{
  "id": 42,
  "name": "Gorgonzola",
  "category": {
    "id": 1,
    "name": "Italian Cheese"
  },
  "photoUrls": [
    "https://wannabechef.com/gorgonzola.jpg"
  ],
  "tags": [
    {
      "id": 1,
      "name": "blue"
    }
  ],
  "status": "available",
  "origin": "Italy",
  "pricePerKg": 28.5,
  "ageMonths": 12,
  "organic": false,
  "createdAt": "2024-01-15T09:30:00Z",
  "updatedAt": "2024-01-15T09:30:00Z"
}

CheeseInput

object
namestringrequired
categoryobject
namestring
photoUrlsArray<string>
tagsArray<object>
namestring
statusstringavailablependingsoldavailable
originstring | null
pricePerKgnumber (float)
ageMonthsinteger[0, 120]
organicbooleanfalse
Example
{
  "name": "string",
  "category": {
    "name": "string"
  },
  "photoUrls": [
    "https://example.com"
  ],
  "tags": [
    {
      "name": "string"
    }
  ],
  "status": "available",
  "origin": "string",
  "pricePerKg": 0,
  "ageMonths": 0,
  "organic": false
}

CheeseList

object

Paginated list of cheeses

itemsArray<object>
idinteger (int64)required

Unique identifier

namestringrequired

Name of the cheese

categoryobject
idinteger (int64)
namestring
photoUrlsArray<string>

URLs of cheese photos

tagsArray<object>

Classification tags

idinteger (int64)
namestring
statusstringavailablependingsoldrequired

Availability status in the store

originstring | null

Country of origin (null if unknown)

pricePerKgnumber (float)

Price per kilogram in USD

ageMonthsinteger[0, 120]

Aging period in months

organicbooleanfalse

Whether the cheese is certified organic

createdAtstring (date-time)

When the cheese was added to the store

updatedAtstring (date-time)

When the cheese was last updated

nextCursorstring | null

Cursor for the next page (null if no more results)

hasMoreboolean

Whether there are more results

totalinteger

Total number of matching cheeses

Example
{
  "items": [
    {
      "id": 42,
      "name": "Gorgonzola",
      "category": {
        "id": 1,
        "name": "Italian Cheese"
      },
      "photoUrls": [
        "https://wannabechef.com/gorgonzola.jpg"
      ],
      "tags": [
        {
          "id": 1,
          "name": "blue"
        }
      ],
      "status": "available",
      "origin": "Italy",
      "pricePerKg": 28.5,
      "ageMonths": 12,
      "organic": false,
      "createdAt": "2024-01-15T09:30:00Z",
      "updatedAt": "2024-01-15T09:30:00Z"
    }
  ],
  "nextCursor": "string",
  "hasMore": true,
  "total": 0
}

Category

object
idinteger (int64)
namestring
Example
{
  "id": 1,
  "name": "Italian Cheese"
}

Tag

object
idinteger (int64)
namestring
Example
{
  "id": 1,
  "name": "blue"
}

Order

object
idinteger (int64)
itemsArray<object>
cheeseIdinteger (int64)
cheeseNamestring
quantityinteger
pricePerKgnumber (float)
shippingAddressobject
streetstringrequired
citystringrequired
statestring | null
zipCodestring
countrystringrequired

ISO 3166-1 alpha-2 country code

statusstringplacedapprovedshippeddeliveredcancelled

Order lifecycle status

notesstring | null

Special instructions for the order

totalnumber (float)

Order total in USD

shipDatestring (date-time) | null

Estimated ship date (null if not yet scheduled)

createdAtstring (date-time)
updatedAtstring (date-time)
Example
{
  "id": 1001,
  "items": [
    {
      "cheeseId": 42,
      "cheeseName": "Gorgonzola",
      "quantity": 3,
      "pricePerKg": 28.5
    },
    {
      "cheeseId": 17,
      "cheeseName": "Brie",
      "quantity": 1,
      "pricePerKg": 22
    }
  ],
  "shippingAddress": {
    "street": "123 Cheese Lane",
    "city": "Cheddarville",
    "state": "WI",
    "zipCode": "53001",
    "country": "US"
  },
  "status": "placed",
  "notes": "Please wrap each wheel separately",
  "total": 114.5,
  "shipDate": null,
  "createdAt": "2026-03-10T14:30:00Z",
  "updatedAt": "2026-03-10T14:30:00Z"
}

OrderInput

object
itemsArray<object>required
cheeseIdinteger (int64)required
quantityinteger[1, 100]required
shippingAddressobjectrequired
streetstringrequired
citystringrequired
statestring | null
zipCodestring
countrystringrequired

ISO 3166-1 alpha-2 country code

notesstring | null
Example
{
  "items": [
    {
      "cheeseId": 0,
      "quantity": 1
    }
  ],
  "shippingAddress": {
    "street": "123 Cheese Lane",
    "city": "Cheddarville",
    "state": "WI",
    "zipCode": "53001",
    "country": "US"
  },
  "notes": "string"
}

OrderItem

object
cheeseIdinteger (int64)
cheeseNamestring
quantityinteger
pricePerKgnumber (float)
Example
{
  "cheeseId": 0,
  "cheeseName": "string",
  "quantity": 1,
  "pricePerKg": 0
}

Address

object
streetstringrequired
citystringrequired
statestring | null
zipCodestring
countrystringrequired

ISO 3166-1 alpha-2 country code

Example
{
  "street": "123 Cheese Lane",
  "city": "Cheddarville",
  "state": "WI",
  "zipCode": "53001",
  "country": "US"
}

Customer

object
idinteger (int64)
usernamestring
firstNamestring

Customer first name

lastNamestring

Customer last name

emailstring (email)
phonestring | null
customerStatusstringbronzesilvergoldplatinum

Customer tier based on purchase volume

favouriteCheeseobject | object

The customer's favourite cheese (by reference or by name)

createdAtstring (date-time)
Example
{
  "id": 1,
  "username": "gordo",
  "firstName": "Alotta",
  "lastName": "Cheese",
  "email": "love@cheese.com",
  "phone": "+3344556677",
  "customerStatus": "gold",
  "favouriteCheese": {
    "id": 42,
    "name": "Gorgonzola",
    "category": {
      "id": 1,
      "name": "Italian Cheese"
    },
    "photoUrls": [
      "https://wannabechef.com/gorgonzola.jpg"
    ],
    "tags": [
      {
        "id": 1,
        "name": "blue"
      }
    ],
    "status": "available",
    "origin": "Italy",
    "pricePerKg": 28.5,
    "ageMonths": 12,
    "organic": false,
    "createdAt": "2024-01-15T09:30:00Z",
    "updatedAt": "2024-01-15T09:30:00Z"
  },
  "createdAt": "2024-01-15T09:30:00Z"
}

CustomerInput

object
usernamestringrequired
firstNamestring
lastNamestring
emailstring (email)required
passwordstring (password)required
phonestring | null
Example
{
  "username": "string",
  "firstName": "string",
  "lastName": "string",
  "email": "user@example.com",
  "password": "********",
  "phone": "string"
}

Error

object
codeinteger (int32)required
typestring
messagestringrequired
Example
{
  "code": 404,
  "type": "Not found",
  "message": "Your cheese has already been eaten"
}

ValidationError

object
codeinteger (int32)
typestring
messagestring
errorsArray<object>

Individual field validation errors

fieldstring

The field that failed validation

messagestring

Human-readable error message

Example
{
  "code": 422,
  "type": "Validation error",
  "message": "Your cheese is not mouldy enough",
  "errors": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}