Prime Fabric Β· Public API v1

Plug your store, site, or stack into your fleet.

Create delivery requests, track jobs live, and get signed webhooks β€” one API key, everything scoped to your fleet. Shopify orders, WordPress bookings, Zapier automations, or raw REST.

Quickstart β€” three calls, five minutes

  1. Mint a key β€” fleet owners go to Fleet β†’ Developer console, name the key, pick scopes, copy the pk_live_… secret (shown once β€” only its SHA-256 digest is stored).
  2. Verify it β€” GET /api/v1/me returns your scopes, plan, and rate limits.
  3. Ship a delivery β€” POST /api/v1/delivery-requests lands a pending request in the fleet's Dispatch queue.
verify + first request
curl https://api.primetransit.com/api/v1/me \
  -H "X-Api-Key: pk_live_…"

curl -X POST https://api.primetransit.com/api/v1/delivery-requests \
  -H "X-Api-Key: pk_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": { "name": "Ava Chen", "email": "ava@example.com", "phone": "+15551234567" },
    "pickup":  { "address": "1200 S Main St, Burbank, CA 91506" },
    "dropoff": { "address": "88 Oak Ave, Glendale, CA 91205" },
    "vehicleClass": "van",
    "scheduledAt": "2026-10-16T15:00:00-07:00",
    "notes": "Order #1042 β€” leave at door"
  }'
201 response
{
  "success": true,
  "requestId": "7f3c…",
  "trackingCode": "PT-8KQ2-MP4R",
  "jobNumber": "PRIME-000482",
  "trackUrl": "https://primetransit.com/track?id=…"
}

Send trackUrl to your customer β€” it's a live tracking page that updates as the fleet accepts, assigns, and completes the delivery.

Authentication & scopes

Every v1 request carries an API key in the X-Api-Key header. Keys are fleet-scoped β€” a key can only read and write its own fleet's data.

Key prefixEnvironmentUse for
pk_live_…LiveProduction traffic β€” real requests hit Dispatch
pk_test_…TestDevelopment and CI β€” same API, flagged for safe testing

Scopes gate every endpoint. A call without the required scope returns 403 listing the missing scopes.

ScopeGrants
jobs:readList and fetch jobs
requests:readList and fetch delivery requests
requests:writeCreate delivery requests (order handoff)
drivers:readList drivers
vehicles:readList vehicles
tracking:readTrack by code or job number
invoices:readList invoices
webhooks:manageRegister/update/delete webhook endpoints

Keys are managed at /fleet/developers or via /api/api-keys (JWT-authenticated). Disable a key instantly with PATCH { "active": false }, or revoke permanently.

Rate limits by plan

Limits are per API key and follow your fleet's subscription. Every response carries headers so you can back off before hitting the wall.

PlanRequests / minuteRequests / day
Free301,000
Starter605,000
Growth12020,000
Enterprise300100,000
HeaderMeaning
X-RateLimit-LimitAllowed requests per minute
X-RateLimit-RemainingRequests left in the current window
X-RateLimit-ResetUnix seconds when the window resets
Retry-AfterSeconds to wait (429 responses only)
429 response β€” honor Retry-After
{
  "success": false,
  "error": "Rate limit exceeded",
  "limit": 30,
  "window": "1 minute",
  "retryAfter": 42
}

Endpoint reference

Base URL: https://api.primetransit.com Β· Lists accept ?limit=1..200&offset=0 and return { data: [...], count: N }.

GET/api/v1/meany key
Key introspection β€” id, fleet, scopes, plan, and effective limits.
GET/api/v1/usageany key
Lifetime call count, last-used timestamp, and plan limits β€” monitor your consumption.
POST/api/v1/delivery-requestsrequests:write

Create a delivery request in the fleet's queue. Same engine as the public booking form β€” the fleet is notified and can accept β†’ assign β†’ dispatch.

body
{
  "customer": { "name": "Ava Chen", "email": "ava@example.com", "phone": "+15551234567" },
  "pickup":  { "address": "1200 S Main St, Burbank, CA", "lat": 34.18, "lng": -118.33 },
  "dropoff": { "address": "88 Oak Ave, Glendale, CA" },
  "serviceType": "delivery",
  "vehicleClass": "van",
  "scheduledAt": "2026-10-16T15:00:00-07:00",
  "packageDetails": { "size": "boxes", "pieces": 3, "weightLbs": 42 },
  "notes": "Order #1042"
}
GET/api/v1/delivery-requestsrequests:read
Filter with ?status=pending|accepted|declined|cancelled|expired.
GET/api/v1/delivery-requests/:idrequests:read
GET/api/v1/jobsjobs:read
Accepted work β€” filter with ?status=.
GET/api/v1/jobs/:idjobs:read
GET/api/v1/tracking/:codetracking:read
Look up a job or request by PT-XXXX-XXXX tracking code or job number.
GET/api/v1/driversdrivers:read
GET/api/v1/vehiclesvehicles:read
GET/api/v1/invoicesinvoices:read
GET/api/v1/webhookswebhooks:manage
POST/api/v1/webhookswebhooks:manage
Register an endpoint. The signing secret is returned once.
PATCH/api/v1/webhooks/:idwebhooks:manage
DELETE/api/v1/webhooks/:idwebhooks:manage
GET/api/v1/webhooks/:id/deliverieswebhooks:manage
Delivery attempt log β€” status, attempts, response code, errors.
POST/api/v1/webhooks/:id/testwebhooks:manage
Fire a signed webhook.test ping β€” verify your receiver end-to-end.
POST/api/v1/webhooks/:id/rotate-secretwebhooks:manage

Request lifecycle

What happens after your POST β€” and which webhook fires at each step.

StageRequest statusJob statusWebhook
Created via API/SMS/webpendingβ€”delivery_request.created
Fleet accepts in Dispatchaccepteddispatchedjob.created + delivery_request β†’ job link
Assigned to a driveracceptedassignedjob.assigned
Driver en route / picked upacceptedin_progressjob.status_changed
Deliveredacceptedcompletedjob.completed
Fleet declinesdeclinedβ€”β€”
TTL expires (48h or pickup+4h)expiredβ€”delivery_request.expired
Cancelledcancelledcancelledjob.cancelled

Poll GET /api/v1/tracking/:code or subscribe to job.status_changed β€” webhooks are the right tool for real-time sync.

Webhooks β€” signed, retried, observable

Register an HTTPS URL and PRIME POSTs signed events. Deliveries retry up to 3 times with exponential backoff (~1s, ~5s + jitter). Every attempt is logged β€” inspect via GET /api/v1/webhooks/:id/deliveries.

HeaderValue
x-prime-eventEvent name, e.g. job.status_changed
x-prime-delivery-idUnique delivery id (use for idempotency)
x-prime-signaturet=<unix-seconds>,v1=<HMAC-SHA256 hex of "t.<raw-body>">
Verify a signature (Node)
const crypto = require('crypto');

function verifyPrimeSignature(rawBody, header, secret) {
  const parts = Object.fromEntries(
    header.split(',').map(kv => kv.split('='))
  );
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${parts.t}.${rawBody}`)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected), Buffer.from(parts.v1 || '')
  );
}
Register an endpoint
curl -X POST https://api.primetransit.com/api/v1/webhooks \
  -H "X-Api-Key: pk_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://your-app.com/hooks/prime", "events": ["delivery_request.created", "job.completed"] }'

Full event catalog: job.*, driver.*, vehicle.*, lead.*, ticket.*, delivery_request.*, payment.*, invoice.*, subscription.*, shift.* β€” or subscribe to * for everything.

Shopify β€” orders become deliveries

No native app install needed: two webhook hops and every paid order lands in Dispatch.

  1. Shopify β†’ your middleware β€” in Shopify Admin β†’ Settings β†’ Notifications β†’ Webhooks, subscribe orders/paid to your endpoint (or use Shopify Flow β†’ "Send HTTP request" on the Advanced plan).
  2. Middleware β†’ Prime Fabric β€” map the order to a delivery request and POST it with your key.
  3. Status back to Shopify β€” subscribe your middleware to job.status_changed and update the order's fulfillment status.
Minimal middleware (Node/Express)
app.post('/shopify/order-paid', express.raw({ type: 'application/json' }), async (req, res) => {
  const order = JSON.parse(req.body);
  const a = order.shipping_address;

  const resp = await fetch('https://api.primetransit.com/api/v1/delivery-requests', {
    method: 'POST',
    headers: {
      'X-Api-Key': process.env.PRIME_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      customer: {
        name: `${a.first_name} ${a.last_name}`,
        email: order.email,
        phone: a.phone || order.phone,
      },
      pickup:  { address: process.env.WAREHOUSE_ADDRESS },
      dropoff: { address: `${a.address1}, ${a.city}, ${a.province_code} ${a.zip}` },
      notes: `Shopify order ${order.name}`,
      packageDetails: {
        weightLbs: order.total_weight ? order.total_weight / 453.6 : undefined,
        pieces: order.line_items.reduce((n, li) => n + li.quantity, 0),
      },
    }),
  });

  const created = await resp.json();
  // created.trackUrl β†’ send to the customer or attach to the order
  res.json({ ok: true, requestId: created.requestId });
});

Zero-code alternative: Zapier/Make β€” trigger on "New Paid Order (Shopify)", action "Webhooks β†’ POST" to /api/v1/delivery-requests with the X-Api-Key header. For simple "book a delivery" buttons on product pages, embed the hosted form (see WordPress section β€” the iframe works anywhere).

WordPress β€” PRIME Booking plugin

The prime-booking plugin embeds your fleet's hosted booking form. Requests land in Dispatch exactly like API-created ones.

  1. Get your fleet's booking slug from Fleet β†’ Integrations (the "Website booking widget" panel also generates the embed snippet).
  2. Upload prime-booking.zip via Plugins β†’ Add New β†’ Upload, activate.
  3. Set the slug under Settings β†’ PRIME Booking.
Shortcodes
[prime_book]          <!-- inline booking form -->
[prime_book_button]   <!-- button that opens the form in a modal -->
[prime_book_button label="Get a delivery quote"]

Deeper integration (order handoff from WooCommerce, custom forms) β†’ use the REST API directly: POST /api/v1/delivery-requests from your theme/plugin PHP with wp_remote_post, same body as the Shopify example.

Booking by SMS β€” zero code

Customers text your fleet's phone number; the platform parses pickup/dropoff with AI, creates a pending delivery request, and replies with a tracking link. No app, no form.

Customer experience
Customer:  "Need a pickup at 1200 S Main St Burbank to 88 Oak Ave Glendale by 3pm"

Fleet #:   "PRIME FLEET received your request!
            Pickup: 1200 S Main St Burbank to 88 Oak Ave Glendale
            Ref: PRIME-000483
            Track: https://primetransit.com/track?id=…
            Reply STOP to unsubscribe."

Telnyx inbound webhook β†’ POST /api/webhooks/telnyx/inbound β†’ AI parse β†’ delivery_request (source=sms) β†’ signed reply. STOP/START/HELP keywords are handled for 10DLC compliance automatically.

Errors & versioning

StatusMeaningFix
400Validation failed β€” message lists the bad fieldsCheck DTO shape
401Missing / invalid / expired / revoked keyVerify X-Api-Key, mint a new one
403Key valid but missing scopeAdd the scope (message names it)
404Resource not found β€” or belongs to another fleetCheck the id
429Rate limitedWait Retry-After seconds
503Upstream dependency unavailableRetry with backoff

Error body: { "statusCode", "message", "error" }. The API is versioned by URL (/api/v1) β€” additive changes (new fields, endpoints, events) ship without a version bump; breaking changes get a new version path.

Feedback & support