Skip to main content

Partner Program API

The Partner Program API is a server-to-server interface for partners who provision and manage FleetQ teams on behalf of their own customers. It is fully separate from the per-user REST API (Sanctum bearer tokens) — partner endpoints live under /api/partner/v1 and authenticate with a single partner key rather than a user token.

Partner programs are created by a FleetQ operator. If you need a partner key, contact your FleetQ account manager — there is no self-service signup for the Partner API.

Authentication

Every request must send your partner key in the X-Partner-Key header. The platform stores only a SHA-256 hash of the key, so the raw value is shown once at creation time and cannot be recovered afterwards.

bash
curl -X POST https://fleetq.net/api/partner/v1/teams \
  -H "X-Partner-Key: pk_finance_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Corp", "owner_email": "[email protected]"}'

Missing or invalid/revoked keys return 401. All partner endpoints are rate-limited to 120 requests/minute; some sensitive endpoints (credit refund, source quotas, cost analytics) carry a tighter 60/min limit.

Team lifecycle

Provision and manage the teams that belong to your partner program. Teams provisioned through the Partner API are linked to your program and are not visible to other partners.

Method Path Purpose
POST /teams Provision a new team (creates the team + owner)
DELETE /teams/{teamId} Destroy a team and its data
POST /teams/{teamId}/members Add a member to a team
DELETE /teams/{teamId}/members/{userId} Remove a member from a team
POST /teams/{teamId}/suspend Suspend a team (halts activity, retains data)
POST /teams/{teamId}/credits/refund Refund platform credits to a team (60/min)

Sub-program scoping & source quotas

A partner key can be scoped to one or more sub-programs. The allowed sub-program slugs are stored in the key's metadata.allowed_sub_programs list (set at key-creation time, or * for all). Sub-program endpoints require the requested {slug} to be in that list, otherwise the request is rejected with 403.

Method Path Purpose
GET /sub-programs/{slug}/cost-analytics Cost & revenue analytics for the sub-program
GET /sub-programs/{slug}/source-quotas List per-team monthly credit caps by source
PUT /sub-programs/{slug}/source-quotas/{teamId} Set/update a team's source quota

Webhooks

Register HTTP endpoints to receive lifecycle events for your program's teams. Webhook endpoints are managed self-service through the Partner API:

Method Path Purpose
GET /webhook-endpoints List registered endpoints
POST /webhook-endpoints Register an endpoint (returns its signing secret)
DELETE /webhook-endpoints/{endpointId} Remove an endpoint
GET /webhook-endpoints/{endpointId}/deliveries Delivery log for an endpoint

Event types

Event Fires when
team.provisioned A team is provisioned for the program
team.suspended A team is suspended
plan.changed A team's plan changes (includes payment context)
pack.purchased A credit pack is purchased (pack key + credits added)
credits.refunded Credits are refunded to a team
credits.reset Monthly credit allotment resets
credits.threshold A team crosses a credit-usage threshold

Delivery, signing & idempotency

Each delivery is a JSON POST with this envelope:

json
{
  "id": "01HX...",
  "event": "team.provisioned",
  "created_at": "2026-06-09T12:00:00+00:00",
  "data": { "team_id": "...", "team_name": "...", "plan": "...", "credits": { } }
}

Headers on every delivery:

Header Value
X-Partner-Signature sha256=<HMAC-SHA256(body, endpoint secret)> — verify before trusting the payload
X-Partner-Event The event type (matches the event field)
X-Partner-Delivery Unique delivery id — use for idempotency / dedup on retries
Compute the HMAC over the raw request body using your endpoint's signing secret, then compare against X-Partner-Signature with a constant-time comparison. Reject deliveries that fail signature verification.

Failed deliveries are retried up to 5 times with exponential backoff (~10s, 30s, 2m, 10m, 1h). After the final attempt the delivery is marked failed. Always treat X-Partner-Delivery as the idempotency key — the same delivery may arrive more than once.

Operator: issuing partner keys

FleetQ operators create a partner program and issue its key with an Artisan command (super-admin only). The raw key is printed once and only the SHA-256 hash is persisted.

bash
php artisan partner-programs:create \
  --name="Finance" \
  --slug=finance \
  --allowed-sub-programs=finance,hr

Pass --allowed-sub-programs=* to allow all sub-programs, or omit it to leave the key without sub-program access (the cost-analytics API then returns 403).