API Documentation
Create and manage FetchBox orders programmatically using your account's API key.
Quick start
- Sign in and generate an API key on the API Keys page.
- Complete one normal checkout so a default payment method is saved on your Stripe customer.
- Send your key as a Bearer token on every request.
Authentication
All endpoints (REST API and webhook) authenticate the same way — pass your API key in theAuthorizationheader:
Authorization: Bearer fb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKeys are scoped to the user that created them. Revoking a key in the UI takes effect immediately.
Base URL
https://bcwiytiszpjhuefxnyik.functions.supabase.co/ordersReturns orders that belong to the API key's owner, newest first.
Query parameters
| Name | Type | Description |
|---|---|---|
| limit | integer | 1–100. Default 25. |
| offset | integer | Pagination offset. Default 0. |
| status | string | Optional filter — e.g. processing, shipped. |
Example request
curl "https://bcwiytiszpjhuefxnyik.functions.supabase.co/orders?limit=10" \
-H "Authorization: Bearer fb_live_..."Example response
{
"ok": true,
"orders": [
{
"id": "f3a1...",
"email": "ship@example.com",
"ship_to": { "firstName": "Jane", "lastName": "Doe", "address": {...} },
"recipient": { "firstName": "John", "lastName": "Smith", "address": {...} },
"kit_id": "standard",
"kit_name": "Fetch IT Kit",
"quantity": 1,
"total": 49.0,
"status": "processing",
"tracking_number": null,
"stripe_payment_intent_id": "pi_3...",
"created_at": "2026-06-29T18:00:00Z"
}
],
"total": 1,
"limit": 10,
"offset": 0
}/ordersCharges the default payment method on your Stripe customer and creates an order. Requires:
- A valid, non-revoked API key
- A confirmed email on the account
- A Stripe customer with a saved default card
Request body
{
"shipTo": {
"firstName": "Jane",
"lastName": "Doe",
"company": "Acme Inc.", // optional
"email": "jane@acme.com",
"address": {
"line1": "123 Main St",
"line2": "Suite 200", // optional
"city": "Austin",
"state": "TX",
"zip": "78701",
"country": "US" // optional, defaults to US
}
},
"recipient": {
"firstName": "John",
"lastName": "Smith",
"email": "john@example.com",
"address": { "line1": "...", "city": "...", "state": "...", "zip": "..." }
},
"quantity": 1, // 1–50, defaults to 1
"promoCode": "WELCOME10" // optional
}Example request
curl -X POST "https://bcwiytiszpjhuefxnyik.functions.supabase.co/orders" \
-H "Authorization: Bearer fb_live_..." \
-H "Content-Type: application/json" \
-d '{
"shipTo": { "firstName":"Jane","lastName":"Doe","email":"jane@acme.com",
"address":{"line1":"123 Main St","city":"Austin","state":"TX","zip":"78701"} },
"recipient":{ "firstName":"John","lastName":"Smith","email":"john@example.com",
"address":{"line1":"500 5th Ave","city":"NYC","state":"NY","zip":"10110"} },
"quantity": 1
}'Success response (201)
{
"ok": true,
"order": {
"id": "f3a1...",
"status": "processing",
"total": 49.0,
"payment_intent_id": "pi_3..."
}
}Error codes
| HTTP | error | When |
|---|---|---|
| 401 | missing_api_key | No Authorization header |
| 401 | invalid_api_key | Unknown or revoked key |
| 400 | invalid_json | Body is not valid JSON |
| 400 | invalid_body | Body fails validation (see details) |
| 400 | invalid_promo | Promo code invalid or fully redeemed |
| 403 | user_not_eligible | Email not confirmed / no email |
| 402 | no_payment_method_on_file | No Stripe customer or no default card |
| 402 | card_declined | Stripe declined the charge (includes code/decline_code) |
| 402 | payment_not_completed | PaymentIntent needs further action |
| 500 | order_persist_failed | DB insert failed — charge auto-refunded |
| 500 | price_unavailable | Stripe price lookup failed |
All errors return JSON: { "error": "...", "message": "..." }
/orders-webhookIdentical behavior to POST /orders. Point external systems (Zapier, n8n, your own backend, etc.) at this URL to create orders.
POST https://bcwiytiszpjhuefxnyik.functions.supabase.co/orders-webhook
Authorization: Bearer fb_live_...
Content-Type: application/json
{ "shipTo": {...}, "recipient": {...}, "quantity": 1, "promoCode": "OPTIONAL" }Same request body, same success/error responses as the create endpoint above. Choose whichever URL is easier to configure in your tool.
Notes & limits
- Quantity is capped at 50 per request.
- Pricing is fetched live from Stripe; promo discounts are applied as a percentage.
- On a successful order, confirmation emails are sent to the ship-to and recipient addresses.
- Treat your API key like a password — anyone with it can place charged orders on your account.