CompuDime API docs

Code samples

Small programs that call the API, ready to run, and a Postman collection with every endpoint. Each reads your key from the environment variable PUBLIC_API_KEY and calls https://api.compudime.com unless you tell it otherwise.

Postman

Download the Postman collection (compudime-api.postman_collection.json). It is generated from the live OpenAPI document: one folder for each section of the reference and one request for each endpoint, with its parameters described and the optional ones switched off.

  1. In Postman, choose Import and pick the file.
  2. Open the collection's variables and set the current value of apiKey to your key. Leave its initial value empty, so the key is never synced or shared. baseUrl is https://api.compudime.com.
  3. Send Describe the calling key (GET /v1/me) first. It is free, and it says which store the key reads and what it may do.

Files

Download a file, or open it below. Never write a key into a file: set PUBLIC_API_KEY in your shell, or in a .env file next to the .http sample. To call another address, set PUBLIC_API_BASE_URL (in the .http sample, change @baseUrl).

FileLanguageWhat it does
order-intake.httpHTTP requests (VS Code REST Client)Ask who your key is, read products, send pickup and delivery orders to POST /v1/orders, and read an order back. Reads your key from a .env file.
curl-products.ps1PowerShell 7Read two pages of products with three fields each, following nextCursor.
javascript-products.mjsJavaScript (Node 18 or later)Read two pages of products, look up one product, and turn an error answer into an exception with its code and requestId.
csharp-products.csC# (.NET 6 or later)Read a page of products with HttpClient and print the problem code and requestId when a call fails.
php-products.phpPHP 8 with curlRead two pages of products, following nextCursor, and raise the problem code and requestId when a call fails.

Orders

Two order APIs share this address. /v1/orders is the public API described here: your app sends an order into a store's POS, then reads where it stands. /api/v1/orders/... is the CompuDime Orders API: delivery and ordering services push orders into a store's queue, and the store's POS collects them from there. They are separate APIs with their own requests and answers. These pages cover /v1/orders only. For the Orders API, write to support@compudime.com.

order-intake.http

Ask who your key is, read products, send pickup and delivery orders to POST /v1/orders, and read an order back. Reads your key from a .env file. HTTP requests (VS Code REST Client).

Download order-intake.http

Show the code
# CompuDime Public API: who am I, products and orders, for the VS Code REST Client extension.
# Docs: https://api.compudime.com/docs (this file and the other samples: https://api.compudime.com/docs/samples)
#
# @baseUrl is the API address. To call another address, change it here.
# @apiKey reads PUBLIC_API_KEY from a .env file next to this one. Never write a key into this file.
#
# Two order APIs share this address. /v1/orders, used below, is the CompuDime Public API: your app sends
# an order into a store's POS, then reads where it stands. /api/v1/orders/... is the CompuDime Orders API,
# where delivery and ordering services push orders into a store's queue. They are separate APIs with their
# own requests and answers; this file covers /v1/orders only.
@baseUrl = https://api.compudime.com
@apiKey = {{$dotenv PUBLIC_API_KEY}}

### Who am I: the key's store, mode (live or test), fields, rate limit and credits; free
GET {{baseUrl}}/v1/me
Authorization: Bearer {{apiKey}}
X-Request-Id: http-who-am-i

### List projected products
GET {{baseUrl}}/v1/products?fields=productCode,description,price&limit=50
Authorization: Bearer {{apiKey}}
X-Request-Id: http-products-page-1

### Lookup one product
GET {{baseUrl}}/v1/products/SKU-100?fields=productCode,description,price
Authorization: Bearer {{apiKey}}
X-Request-Id: http-product-lookup

### POST /v1/orders requires orders.write and a safe Idempotency-Key
# With a test key (cc_test_ or cd_test_) the order is validated and simulated: the 202 says
# dispatchState simulated and an orderId starting test_, and the order never reaches the store.
POST {{baseUrl}}/v1/orders
Authorization: Bearer {{apiKey}}
Idempotency-Key: web-order-1001
X-Request-Id: http-order-create-1001
Content-Type: application/json

{
  "externalOrderId": "web-1001",
  "customer": "Pickup customer",
  "notes": "Paid online",
  "orderMethod": "pickup",
  "lines": [
    {
      "productCode": "SKU-100",
      "quantity": 2,
      "unitPrice": "3.99"
    }
  ]
}

### A delivery with its address (shipTo): street, city, state and zip together; limits are the POS invoice widths
POST {{baseUrl}}/v1/orders
Authorization: Bearer {{apiKey}}
Idempotency-Key: web-order-1002
X-Request-Id: http-order-create-1002
Content-Type: application/json

{
  "externalOrderId": "web-1002",
  "customer": "(732) 555-0142",
  "notes": "Ring twice",
  "shipTo": {
    "firstName": "Rivka",
    "lastName": "Klein",
    "street": "1200 Madison Ave",
    "street2": "Apt 4B",
    "city": "Lakewood",
    "state": "NJ",
    "zip": "08701-1234",
    "phone": "(732) 555-0199"
  },
  "lines": [
    {
      "productCode": "SKU-100",
      "quantity": 2,
      "unitPrice": "3.99"
    }
  ]
}

### A line without unitPrice is priced by the store at dispatch under its price rule (register: what the store's register charges, with the customer's discount; order_screen: the regular price), or the customer's contract price; an item sold by weight sends its weight in pounds; the order reads return what the store charged as storePrices and storeDiscount
POST {{baseUrl}}/v1/orders
Authorization: Bearer {{apiKey}}
Idempotency-Key: web-order-1003
X-Request-Id: http-order-create-1003
Content-Type: application/json

{
  "externalOrderId": "web-1003",
  "customer": "(732) 555-0142",
  "lines": [
    { "productCode": "SKU-100", "quantity": 2, "unitPrice": "3.99" },
    { "productCode": "0006009", "quantity": 1 },
    { "productCode": "4011", "quantity": 1, "weight": "1.37" }
  ]
}

### GET /v1/orders/{orderId} requires orders.read; put the orderId from the 202 in place of <ORDER_ID>
GET {{baseUrl}}/v1/orders/<ORDER_ID>
Authorization: Bearer {{apiKey}}
X-Request-Id: http-order-status-1001

### What the store charged for the lines sent without unitPrice, and the customer's discount on them (after dispatch)
GET {{baseUrl}}/v1/orders/external/web-1003?fields=dispatchState,storePrices,storeDiscount
Authorization: Bearer {{apiKey}}
X-Request-Id: http-order-store-prices-1003

# Errors are problem JSON sent as application/json (not application/problem+json); every code, for example
# rate_limited, usage_exhausted, billing_card_missing, is at https://api.compudime.com/docs/errors

curl-products.ps1

Read two pages of products with three fields each, following nextCursor. PowerShell 7.

Download curl-products.ps1

Show the code
$ErrorActionPreference = "Stop"

$baseUrl = ($env:PUBLIC_API_BASE_URL ?? "https://api.compudime.com").TrimEnd("/")
$apiKey = $env:PUBLIC_API_KEY
if ([string]::IsNullOrWhiteSpace($apiKey)) {
    throw "Set PUBLIC_API_KEY to <PUBLIC_API_KEY> before running this example."
}

$headers = @{
    Authorization  = "Bearer $apiKey"
    "X-Request-Id" = "catalog-sync-$([guid]::NewGuid().ToString("N"))"
}

$fields = [uri]::EscapeDataString("productCode,description,price")
$page = Invoke-RestMethod -Method Get -Headers $headers -Uri "$baseUrl/v1/products?fields=$fields&limit=50"

$page.products | Select-Object productCode, description, price

if ($page.nextCursor) {
    $cursor = [uri]::EscapeDataString($page.nextCursor)
    $next = Invoke-RestMethod -Method Get -Headers $headers -Uri "$baseUrl/v1/products?fields=$fields&limit=50&cursor=$cursor"
    "Fetched $($next.products.Count) products from the next page."
}

javascript-products.mjs

Read two pages of products, look up one product, and turn an error answer into an exception with its code and requestId. JavaScript (Node 18 or later).

Download javascript-products.mjs

Show the code
const baseUrl = (process.env.PUBLIC_API_BASE_URL || "https://api.compudime.com").replace(/\/$/, "");
const apiKey = process.env.PUBLIC_API_KEY;

if (!apiKey) {
  throw new Error("Set PUBLIC_API_KEY to <PUBLIC_API_KEY> before running this example.");
}

async function request(path, requestId) {
  const response = await fetch(`${baseUrl}${path}`, {
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "X-Request-Id": requestId,
    },
  });

  if (!response.ok) {
    const problem = await response.json();
    throw new Error(`Public API problem JSON ${problem.code} (${problem.requestId}): ${problem.detail}`);
  }

  return response.json();
}

const fields = encodeURIComponent("productCode,description,price");
const firstPage = await request(`/v1/products?fields=${fields}&limit=50`, "js-products-page-1");
console.table(firstPage.products);

if (firstPage.nextCursor) {
  const cursor = encodeURIComponent(firstPage.nextCursor);
  const secondPage = await request(`/v1/products?fields=${fields}&limit=50&cursor=${cursor}`, "js-products-page-2");
  console.log(`Fetched ${secondPage.products.length} products from the nextCursor page.`);
}

const lookup = await request("/v1/products/SKU-100?fields=productCode,description,price", "js-product-lookup");
console.log(lookup.product ?? lookup);

csharp-products.cs

Read a page of products with HttpClient and print the problem code and requestId when a call fails. C# (.NET 6 or later).

Download csharp-products.cs

Show the code
using System.Net.Http.Headers;
using System.Text.Json;

var baseUrl = (Environment.GetEnvironmentVariable("PUBLIC_API_BASE_URL") ?? "https://api.compudime.com").TrimEnd('/');
var apiKey = Environment.GetEnvironmentVariable("PUBLIC_API_KEY");
if (string.IsNullOrWhiteSpace(apiKey))
{
    throw new InvalidOperationException("Set PUBLIC_API_KEY to <PUBLIC_API_KEY> before running this example.");
}

using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
http.DefaultRequestHeaders.Add("X-Request-Id", "csharp-products-001");

var fields = Uri.EscapeDataString("productCode,description,price");
using var response = await http.GetAsync($"{baseUrl}/v1/products?fields={fields}&limit=50");
var body = await response.Content.ReadAsStringAsync();

if (!response.IsSuccessStatusCode)
{
    using var problemJson = JsonDocument.Parse(body);
    var root = problemJson.RootElement;
    throw new InvalidOperationException($"Public API problem JSON {root.GetProperty("code").GetString()} ({root.GetProperty("requestId").GetString()}): {root.GetProperty("detail").GetString()}");
}

using var productsJson = JsonDocument.Parse(body);
foreach (var product in productsJson.RootElement.GetProperty("products").EnumerateArray())
{
    Console.WriteLine($"{product.GetProperty("productCode").GetString()} {product.GetProperty("description").GetString()} {product.GetProperty("price").GetString()}");
}

if (productsJson.RootElement.TryGetProperty("nextCursor", out var nextCursor))
{
    Console.WriteLine($"Use nextCursor to request the next page: {nextCursor.GetString()}");
}

php-products.php

Read two pages of products, following nextCursor, and raise the problem code and requestId when a call fails. PHP 8 with curl.

Download php-products.php

Show the code
<?php
$baseUrl = rtrim(getenv('PUBLIC_API_BASE_URL') ?: 'https://api.compudime.com', '/');
$apiKey = getenv('PUBLIC_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set PUBLIC_API_KEY to <PUBLIC_API_KEY> before running this example.');
}

function public_api_get(string $baseUrl, string $path, string $apiKey, string $requestId): array {
    $curl = curl_init($baseUrl . $path);
    curl_setopt_array($curl, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . $apiKey,
            'X-Request-Id: ' . $requestId,
        ],
    ]);

    $body = curl_exec($curl);
    $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    if ($body === false) {
        throw new RuntimeException(curl_error($curl));
    }
    curl_close($curl);

    $decoded = json_decode($body, true, flags: JSON_THROW_ON_ERROR);
    if ($status < 200 || $status >= 300) {
        throw new RuntimeException('Public API problem JSON ' . $decoded['code'] . ' (' . $decoded['requestId'] . '): ' . $decoded['detail']);
    }
    return $decoded;
}

$fields = rawurlencode('productCode,description,price');
$page = public_api_get($baseUrl, "/v1/products?fields={$fields}&limit=50", $apiKey, 'php-products-page-1');
foreach ($page['products'] as $product) {
    echo $product['productCode'] . ' ' . $product['description'] . ' ' . $product['price'] . PHP_EOL;
}

if (!empty($page['nextCursor'])) {
    $cursor = rawurlencode($page['nextCursor']);
    $next = public_api_get($baseUrl, "/v1/products?fields={$fields}&limit=50&cursor={$cursor}", $apiKey, 'php-products-page-2');
    echo 'Fetched ' . count($next['products']) . ' products from the nextCursor page.' . PHP_EOL;
}