Organization API — v1

Issue access credits from your own systems.

A minimal REST surface. Bearer-key auth, HMAC-signed webhooks, sandbox environment for testing before you commit real balance.

Base URLs

Auth

All API calls require the header x-org-api-key with a key we issue when your account is provisioned. Keys are rotatable from the admin surface. Losing a key does not lose funded balance — rotate and the previous key is immediately invalidated.

curl -sS https://kwxdkuljhwdbwqvzdgpw.supabase.co/functions/v1/org-issue-credits \
  -H "x-org-api-key: $YOUR_ORG_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient_email": "student@example.edu",
    "amount_cents": 5000,
    "metadata": {"cohort": "fall-2026", "program": "cs-101"}
  }'

Endpoints

POST /org-issue-credits

Deducts amount_cents from your funded balance, mints an access card, emails the recipient.

Request body:

{
  "recipient_email": "string, required, valid email",
  "amount_cents": "integer, required, min 1000 (=$10), max 100000 (=$1000)",
  "metadata": "object, optional, key/value pairs echoed on ledger and webhook",
  "expires_days": "integer, optional, default 1825 (5 years), max 1825"
}

Response (200):

{
  "success": true,
  "card_id": "uuid",
  "card_code": "AIG-XXXX-XXXX-XXXX",
  "redemption_url": "https://youraiaccess.com/redeem.html?c=...",
  "expires_at": "2031-08-11T00:00:00Z",
  "balance_remaining_cents": 4950000
}

Error responses:

GET /org-balance

Returns your current funded balance, committed balance (pending redemptions), and used balance.

{
  "balance_cents": 4950000,
  "committed_cents": 250000,
  "used_cents": 800000,
  "last_topup_at": "2026-08-01T14:22:11Z"
}

GET /org-events?since=...

Returns the audit event stream for your org since the given ISO timestamp. Paginated at 200 events per page. Useful for warm-start recovery if you missed webhook deliveries.

Webhooks

Configure a single webhook URL from the admin surface. We POST JSON to it for every credit lifecycle event. Every request carries an X-Signature header — a lowercase-hex HMAC-SHA256 of the raw request body, signed with your webhook secret.

Verify the signature before trusting the payload. Sample (Node):

const crypto = require('crypto');
function verify(rawBody, secret, signature){
  const expected = crypto.createHmac('sha256', secret)
    .update(rawBody, 'utf8').digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected, 'hex'),
    Buffer.from(signature, 'hex')
  );
}

credit.issued

{
  "event": "credit.issued",
  "event_id": "uuid",
  "created_at": "2026-08-11T18:00:00Z",
  "data": {
    "card_id": "uuid",
    "card_code": "AIG-...",
    "recipient_email": "student@example.edu",
    "amount_cents": 5000,
    "metadata": {"cohort":"fall-2026"}
  }
}

credit.redeemed

{
  "event": "credit.redeemed",
  "event_id": "uuid",
  "created_at": "2026-08-14T09:12:33Z",
  "data": {
    "card_id": "uuid",
    "card_code": "AIG-...",
    "provider_id": "uuid",
    "provider_name": "ChatGPT",
    "amount_redeemed_cents": 2000,
    "remaining_cents": 3000,
    "recipient_email": "student@example.edu"
  }
}

credit.expired

{
  "event": "credit.expired",
  "event_id": "uuid",
  "created_at": "2031-08-11T00:00:00Z",
  "data": {
    "card_id": "uuid",
    "card_code": "AIG-...",
    "unredeemed_cents": 3000
  }
}

Delivery + retry

We retry failed deliveries with exponential backoff — 3 attempts total, at 30s, 5min, and 30min after the first failure. Any 2xx response is treated as success. After the third failure we mark the event as delivery_failed and surface it in the org admin dashboard. Use GET /org-events to replay.

Rate limits

Exceeding a limit returns HTTP 429 with a Retry-After header (seconds).

Idempotency

Pass an Idempotency-Key header (any string ≤ 128 chars) to make issuance safely retryable. Repeats within 24 hours return the original response without re-issuing the card.

Sandbox

Add X-Sandbox: true to any call. Sandbox mode:

Support

For integration help: bill@bdsrvs.com. We respond within 1 business day and can jump on a call for onboarding of accounts $10K+.

Ready — set up an org account →