PetroSupportdevelopers
Documentation / Partner API

Connect your systems.
Coordinate your response.

Integrate fleet drivers, incident activation, response progress, and signed events into your own software. Start with synthetic sandbox data, then request access to your verified organization.

Keep your fleet system

Map your existing driver IDs to PetroSupport accounts. Drivers use our app; your system remains your operational source.

Fleet integration guide →

Follow every service

Create one incident with independent medical, security, and recovery tasks. Read progress or reconcile signed events.

Incident API →

The credential determines the environment and permitted organization. Sandbox data never dispatches real responders.

Quickstart

From account to first incident.

1

Create your account

Register to receive a sandbox application automatically. Open your console and create a credential.

2

Configure your server

Set PETROSUPPORT_BASE_URL to https://petrosupportea.com/api/partner/v1, PETROSUPPORT_TOKEN to your credential, and PETROSUPPORT_IDEMPOTENCY_KEY to a unique operation ID. Persist the key and request bytes before sending.

3

Create a sandbox incident

The test UUID below works in the sandbox. Production requires an active driver in your approved fleet. These are native HTTP reference examples, not packaged SDKs.

# Set PETROSUPPORT_BASE_URL, PETROSUPPORT_TOKEN and PETROSUPPORT_IDEMPOTENCY_KEY.
# The base URL includes /api/partner/v1. Use a fresh key for each new operation.
curl --fail-with-body --max-time 20 \
  "$PETROSUPPORT_BASE_URL/incidents" \
  -H "Authorization: Bearer $PETROSUPPORT_TOKEN" \
  -H "Idempotency-Key: $PETROSUPPORT_IDEMPOTENCY_KEY" \
  -H 'Content-Type: application/json' \
  --data-binary '{"title":"Fleet roadside incident","priority":"high","requested_by":"11111111-1111-4111-a111-111111111111","latitude":-1.292100000000000026290081223123706877231597900390625,"longitude":36.821899999999999408828443847596645355224609375,"services":["recovery"],"external_reference":"FLEET-INC-001"}'

Download an example: cURLPHPRubyGoJavaScriptPython

Save data.id and data.tasks[].id. Read GET /incidents/{incident} for current state. Advance your test response with the simulator.

Example successful response
201 Created
{
  "data": {
    "id": "22222222-2222-4222-a222-222222222222",
    "environment": "sandbox",
    "external_reference": "FLEET-INC-001",
    "title": "Fleet roadside incident",
    "priority": "high",
    "status": "open",
    "tasks": [{"id": "33333333-3333-4333-a333-333333333333", "service": "recovery", "status": "requested"}],
    "latest_sequence": 1,
    "created_at": "2026-10-21T09:00:00.000000Z"
  }
}
Security

One application. Explicit permissions.

Send Authorization: Bearer <credential> on every API request. The credential contains an identifier and a secret. Console-issued credentials expire after 90 days and can be revoked immediately. This release uses scoped bearer credentials; there is no OAuth token exchange.

Authorization: Bearer YOUR_CREDENTIAL
Accept: application/json
Content-Type: application/json
Idempotency-Key: your-persisted-operation-id

Store credentials on your server. Your mobile app or browser calls your backend, which calls PetroSupport. Create a replacement, switch your backend, then revoke the old key. A credential cannot select another organization through a header or request field.

Open the visual simulator · Open the authenticated API playground

The simulator uses internal sandbox lifecycle actions with synthetic route markers. Delay and unavailable-responder exercises are local training controls, not recorded availability outcomes. The playground authenticates your supplied sandbox bearer credential through normal API checks. Neither tool certifies your external HTTP client or receiver.

Test safely

A simulated response lifecycle.

Sandbox incidents are isolated. They do not notify responders, dispatch vehicles, or create real driver accounts. Sandbox webhooks can reach your receiver; use a dedicated test endpoint.

Call POST /simulations with a new idempotency key for each transition:

POST /simulations
{
  "incident_id": "22222222-2222-4222-a222-222222222222",
  "task_id": "33333333-3333-4333-a333-333333333333",
  "status": "accepted"
}

requested → accepted → en_route → arrived → working → completed. An arrived task may also complete directly. All tasks must complete before the incident closes. Production credentials cannot use the simulator.

Go live

Apply when your integration is ready.

1

Test your lifecycle

Exercise activation, duplicate retries, event reconciliation, errors, and signature validation. Fleet customers should also test driver synchronization and invitations.

2

Submit your production application

Use your console to submit your legal organization, website, use case, test evidence, and requested scopes. Track review notes there.

3

Receive separate production access

An administrator verifies your authority, links a verified organization and service identity, and grants permissions. Approval creates a separate production application. Sandbox data stays isolated. Deployment activation is also required before live credentials can be issued.

Coverage is not a reservation. Incident creation confirms persistence. Dispatch, acceptance, and physical arrival are separate outcomes.

Bring your own fleet system

Your software. Our driver and response platform.

Keep your existing fleet management system. Synchronize a driver using a stable external ID, invite that driver into our app, and activate incidents using the returned PetroSupport driver ID. Your ERP or fleet system can remain the roster source.

StepActionResult
SynchronizePUT /fleet/drivers/EMP-0042Map your ID to a driver in your approved organization.
InvitePOST /fleet/drivers/EMP-0042/invitationSend a single-use password setup link; no password is returned.
OperateDriver signs into the PetroSupport Driver appUse app workflows for checks, journeys, and emergency response.
CoordinatePOST /incidents with returned driver_idFollow response tasks and events in your system.
ReportConsole and organization reportsExport scoped usage alongside existing operational reports.
PUT /fleet/drivers/EMP-0042
{
  "first_name": "Test",
  "last_name": "Driver",
  "email": "driver42@example.com",
  "phone": "+254700000042",
  "status": "active"
}

Requires fleet:write and an idempotency key. Sandbox returns a simulated ID. Production creates a driver awaiting invitation acceptance. Send {} to the invitation endpoint. A 202 response records the request; it does not prove email delivery. Invitations expire after 24 hours. If delivery fails, request another with a new key after the five-minute cooldown.

An external ID is scoped to one application. Existing email/phone identities cannot be claimed automatically; an administrator must resolve conflicts. Contact identity changes require review. Setting status: inactive deactivates only this organization's membership. Vehicle synchronization, telematics ingestion, partner journey assignment, and linking pre-existing accounts are further extensions.

Open the webhook inspector to review delivery outcomes and attempt history recorded since installation. Terminal sandbox deliveries can be queued again with the original event ID. Production replay remains an administrator action. Test duplicate and older-event delivery at your receiver; queue order is not guaranteed. HTTP acknowledgement does not prove signature verification or business processing.

Event-driven integrations

Receive updates you can verify.

Register a public HTTPS receiver with POST /webhook-endpoints. Store the signing secret returned by registration. Verify the exact raw bytes before parsing:

Signature contract
X-PetroSupport-Event-ID: <event UUID>
X-PetroSupport-Delivery-ID: <delivery UUID>
X-PetroSupport-Timestamp: <Unix seconds>
X-PetroSupport-Signature: v1=<hex digest>

signed_message = timestamp + "." + raw_body
digest = HMAC_SHA256(signing_secret, signed_message)

Compare signatures in constant time. Reject timestamps outside your accepted window, for example five minutes. Persist event IDs before processing. Events may repeat or arrive out of order; reconcile sequence gaps with GET /incidents/{incident}/events?after=LAST_SEQUENCE. Return 2xx after durable acceptance.

Endpoints require public HTTPS DNS on port 443, without URL credentials, queries, fragments, IP literals, or redirects. Up to ten enabled endpoints are supported. Failed deliveries retry after 30, 60, 120, 240, and 480 seconds, subject to worker cadence, before the sixth failure becomes terminal. Read GET /webhook-deliveries for outcomes. Rotate secrets by registering a replacement and disabling the old endpoint after switching.

Reliable clients

Handle uncertainty without duplicate incidents.

Every write requires an Idempotency-Key: 8–128 letters, digits, dots, underscores, colons, or hyphens. Persist it with the exact request bytes. Retry uncertain results using the same method, path, key, and bytes. Different content with the same key returns 409. Successful replays include Idempotent-Replayed: true; read current state separately. Failed validation is not retained. Keys stay reserved for the application's lifetime.

Bodies are limited to 64 KiB. Rate limits appear in X-RateLimit-Limit and X-RateLimit-Remaining. Respect Retry-After on 429 and use bounded backoff for transient failures. Timestamps use UTC. Incident lists accept page and per_page (up to 100); driver lists use 50 per page. Events use after and limit (up to 100).

HTTPAction
401Check expiry, revocation, and bearer credential.
403Check scopes, environment, account status, and organization authorization.
404Resource is missing or belongs to another application.
409Reconcile idempotency, lifecycle, or identity conflicts.
422Correct validation errors before retrying.
429Wait for Retry-After.
503Access is unavailable; retain the operation and reconcile safely.

Responses include X-Request-ID. Provide support the request ID, application ID, endpoint, and UTC time. Exclude credentials and patient records. Clients must tolerate additive fields and new event types; breaking contracts require a new major API version.

API reference

Endpoints and field definitions.

Base URL: https://petrosupportea.com/api/partner/v1. This reference shares its contract with the OpenAPI 3.1 download.

GET/fleet/drivers

List drivers mapped by this application

Required scope fleet:read

Parameters

NameLocationTypeRequired
pagequeryintegerNo
Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataarray
metaPageMeta
meta.page · integer
meta.last_page · integer

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

PUT/fleet/drivers/{external}

Create or update a driver using your external ID

Required scope fleet:write

Parameters

NameLocationTypeRequired
externalpathstringYes
Idempotency-KeyheaderstringYes

JSON body

FieldTypeRequiredRules
first_namestringYes Max 100 characters.
last_namestringYes Max 100 characters.
emailstringYes Max 191 characters.
phonestringYes Max 20 characters.
statusstringYes active, inactive
Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataFleetDriver
data.external_id · string
data.driver_id · string
data.environment · string
data.first_name · string
data.last_name · string
data.email · string
data.phone · string
data.status · string
data.account_ready · boolean

201 · Driver mapping created

FieldTypeDescription
dataFleetDriver
data.external_id · string
data.driver_id · string
data.environment · string
data.first_name · string
data.last_name · string
data.email · string
data.phone · string
data.status · string
data.account_ready · boolean

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

POST/fleet/drivers/{external}/invitation

Request a single-use driver setup invitation

Required scope fleet:write

Parameters

NameLocationTypeRequired
externalpathstringYes
Idempotency-KeyheaderstringYes

JSON body

Send an empty JSON object: {}.

Response fields and HTTP statuses

202 · Successful operation

FieldTypeDescription
dataDriverInvitation
data.external_id · string
data.invitation_status · string
data.email_sent · boolean | null
data.expires_in_seconds · integer

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

GET/services

List supported services

Required scope services:read

Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataServiceCatalogue
data.version · string
data.services · array
data.dispatch · string

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

GET/coverage

Assess available matching capacity; does not reserve a unit

Required scope coverage:read

Parameters

NameLocationTypeRequired
latitudequerynumberYes
longitudequerynumberYes
servicequerystringYes
Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataCoverageAssessment
data.environment · string
data.service · string
data.coverage_status · string
data.candidate_count · integer
data.availability_confirmed · boolean
data.observed_at · string

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

GET/incidents

List incidents created by this application

Required scope incidents:read

Parameters

NameLocationTypeRequired
pagequeryintegerNo
per_pagequeryintegerNo
Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataarray
metaobject

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

POST/incidents

Create an incident without automatic dispatch

Required scope incidents:write

Parameters

NameLocationTypeRequired
Idempotency-KeyheaderstringYes

JSON body

FieldTypeRequiredRules
titlestringYes Max 180 characters.
prioritystringYes critical, high, normal
requested_bystringYesActive fleet driver UUID; sandbox accepts a test UUID.
latitudenumberYes Minimum -90. Maximum 90.
longitudenumberYes Minimum -180. Maximum 180.
servicesarrayYes Values: medical, security, recovery.
external_referencestringNo Max 120 characters.
requirementsobjectNo
Response fields and HTTP statuses

201 · Successful operation

FieldTypeDescription
dataIncident
data.id · string
data.environment · string
data.external_reference · string | null
data.title · string
data.priority · string
data.status · string
data.tasks · array
data.latest_sequence · integer
data.created_at · string

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

GET/incidents/{incident}

Read incident and service task states

Required scope incidents:read

Parameters

NameLocationTypeRequired
incidentpathstringYes
Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataIncident
data.id · string
data.environment · string
data.external_reference · string | null
data.title · string
data.priority · string
data.status · string
data.tasks · array
data.latest_sequence · integer
data.created_at · string

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

GET/incidents/{incident}/events

Reconcile ordered incident events

Required scope incidents:read

Parameters

NameLocationTypeRequired
incidentpathstringYes
afterqueryintegerNo
limitqueryintegerNo
Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataarray
metaobject

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

POST/incidents/{incident}/tasks/{task}/dispatch

Live only: offer task to eligible providers

Required scope dispatch:write

Parameters

NameLocationTypeRequired
incidentpathstringYes
taskpathstringYes
Idempotency-KeyheaderstringYes

JSON body

Send an empty JSON object: {}.

Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataDispatchResult
data.task_id · string
data.offered_count · integer
data.message · string

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

POST/simulations

Sandbox only: advance a simulated response stage

Required scope incidents:write

Parameters

NameLocationTypeRequired
Idempotency-KeyheaderstringYes

JSON body

FieldTypeRequiredRules
incident_idstringYes
task_idstringYes
statusstringYes accepted, en_route, arrived, working, completed
Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataIncident
data.id · string
data.environment · string
data.external_reference · string | null
data.title · string
data.priority · string
data.status · string
data.tasks · array
data.latest_sequence · integer
data.created_at · string

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

GET/webhook-endpoints

List endpoints without signing secrets

Required scope webhooks:manage

Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataarray

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

POST/webhook-endpoints

Register an endpoint and receive signing secret

Required scope webhooks:manage

Parameters

NameLocationTypeRequired
Idempotency-KeyheaderstringYes

JSON body

FieldTypeRequiredRules
urlstringYes Max 2048 characters.
eventsarrayYes Values: incident.created, incident.closed, task.offered, task.accepted, task.en_route, task.arrived, task.working, task.completed, task.status_changed, incident.simulated.
Response fields and HTTP statuses

201 · Successful operation

FieldTypeDescription
dataWebhookIssued
data.id · string
data.url · string
data.signing_secret · string
data.events · array

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

DELETE/webhook-endpoints/{webhook}

Disable an owned endpoint

Required scope webhooks:manage

Parameters

NameLocationTypeRequired
webhookpathstringYes
Idempotency-KeyheaderstringYes

JSON body

Send an empty JSON object: {}.

Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataWebhookDisabled
data.id · string
data.enabled · boolean

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.

GET/webhook-deliveries

Read delivery attempts and outcomes

Required scope webhooks:manage

Parameters

NameLocationTypeRequired
pagequeryintegerNo
Response fields and HTTP statuses

200 · Successful operation

FieldTypeDescription
dataarray
metaPageMeta
meta.page · integer
meta.last_page · integer

Other statuses: 400, 401, 403, 404, 409, 413, 415, 422, 429, 500, 503. See error handling.