Raptors Freight & Packaging
Try ItYour KeysLog In

Raptors Freight & Packaging API v1

Book, price, track and pay for shipments from your own systems. Base URL: https://raptorsfreight.live/api/v1

Getting Started

  1. Log in and open Developer API; create a key, tick the scopes it needs, and copy it once.
  2. Send it as Authorization: Bearer rfp_… on every call. JSON in, JSON out.
  3. Start with a test key (rfp_test_…): it reads your real data but never books or charges anything.
curl -H "Authorization: Bearer rfp_…" https://raptorsfreight.live/api/v1/usage

Authentication

Two credentials are accepted and behave the same: an API key from the Developer portal (long-lived, revocable, scoped) or a JWT from /auth/login + /auth/verify-login-otp (one hour, every scope — it is the app). Keys are hashed at rest; a lost key is revoked, not recovered.

Scopes

ScopeOpens
readRead shipments, packages, consolidations, tracking, profile, recipients, pre-alerts
quotesPrice a hypothetical shipment and read public rates
shipments:writeBook shipments and create pre-alerts
recipients:writeCreate recipients
invoicesRead bills and payment state
payments:writeStart a payment for a bill
deliveriesRead last-mile delivery status
webhooksManage webhook subscriptions

A call the key is not scoped for answers 403 with errors.required_scope.

Sandbox

Create a key with Test Key ticked. It is prefixed rfp_test_, reads your own shipments, bills and tracking, and on POST /shipments or POST /payments answers 201 with "sandbox": true and a simulated reference — nothing is saved, nothing is charged. Webhooks created with a test key may use http and receive test events only ("sandbox": true in the body); live endpoints must be https and never receive test events.

Rate Limits

Default 60 requests per minute per key (sliding window). Every response carries X-RateLimit-Limit and X-RateLimit-Remaining; past the limit you get 429 with Retry-After. Need more? Ask support — limits are set per key.

Responses

{"status":"success","code":200,"message":"…","data":{…},"meta":{…}}
{"status":"error","code":422,"message":"…","errors":{"field":"why"}}

Lists take ?page=1&per_page=25 (max 100) and return meta.total.

Authentication

scope public POST/auth/register

Start a customer registration (OTP sent).

{"fname":"Ama","lname":"Mensah","email":"ama@example.com","phone":"0244000000","password":"…"}
scope public POST/auth/verify-register-otp

Finish registration with the OTP.

{"email":"ama@example.com","otp":"123456"}
scope public POST/auth/login

Start a login (OTP sent).

{"username":"ama","password":"…"}
scope public POST/auth/verify-login-otp

Finish login; returns a JWT (1 hour).

{"username":"ama","otp":"123456"}
scope any GET/auth/me

The caller's account.

Quotes & Rates

scope quotes POST/quotes

Price a hypothetical shipment. Indicative — the invoice follows the weight confirmed at the warehouse.

{"mode":"air","items":[{"weight":3,"length":10,"width":8,"height":6,"description":"Phone","declared_value":300}]}
scope quotes GET/rates

The public rate cards and the global rate.

Shipments

scope read GET/shipments

Your shipments (paginated: page, per_page).

scope read GET/shipments/{id}

One shipment.

scope read GET/shipments/{id}/tracking

Its tracking events.

scope shipments:write POST/shipments

Book a shipment. mode air|sea|courier; recipient_id optional (must be yours); from{city,state,country,zip,address} optional. Dangerous goods must be booked on the website.

{"mode":"air","recipient_id":845,"items":[{"weight":4,"length":12,"width":10,"height":8,"description":"Laptop","declared_value":800}],"from":{"city":"Houston","state":"TX","country":"United States"}}
scope public GET/tracking/{reference}

Public tracking by reference.

Packages, Pre-Alerts, Recipients

scope read GET/packages

Locker packages.

scope read GET/prealerts

Your pre-alerts.

scope shipments:write POST/prealerts

Register a pre-alert.

{"tracking":"1Z999","provider":"Amazon","courier":"UPS","price":120,"description":"Shoes","date":"2026-08-20"}
scope read GET/recipients

Your recipients.

scope recipients:write POST/recipients

Create a recipient.

{"fname":"Kofi","lname":"Owusu","phone":"0244111222","email":"kofi@example.com"}
scope read GET/consolidations

Consolidations your packages ride on.

Invoices & Payments

scope invoices GET/invoices

Your bills with paid and balance.

scope invoices GET/invoices/{consolidation_id}

One bill, its packages and payments.

scope payments:write POST/payments

Start a payment. gateway paystack|hubtel|hubtel_direct; amount_ghs defaults to the balance; return_url optional. Returns a checkout_url (or a phone prompt for hubtel_direct).

{"consolidation_id":181,"gateway":"paystack","amount_ghs":250}
scope invoices GET/payments/{reference}

The payment's state.

Deliveries

scope deliveries GET/deliveries/{shipment_id}

Last-mile state: rider, slot, ETA, attempts, proof.

Webhooks

scope webhooks GET/webhooks

Your endpoints.

scope webhooks POST/webhooks

Subscribe an https endpoint to events (["*"] for all). The secret is returned once.

{"url":"https://example.com/raptors","events":["shipment.status","payment.received"]}
scope webhooks POST/webhooks/{id}/test

Send a signed ping now.

scope webhooks GET/webhooks/{id}/deliveries

The last 100 deliveries and their outcomes.

scope webhooks DELETE/webhooks/{id}

Remove an endpoint.

Account

scope any GET/usage

This key's usage, scopes and limit.

scope public GET/scopes

The scope and event vocabulary.

scope read GET/notifications

In-app notifications.

scope read GET/profile

Your profile.

Webhook Signing

Events: shipment.created shipment.status payment.received bill.issued delivery.updated prealert.created ticket.replied

Every delivery is a JSON POST with headers X-Raptors-Event, X-Raptors-Event-Id, X-Raptors-Timestamp and X-Raptors-Signature: sha256=…. Verify with your secret:

expected = "sha256=" + HMAC_SHA256(secret, timestamp + "." + raw_body)
accept only if expected == X-Raptors-Signature and |now - timestamp| < 5 minutes
{"id":"evt_…","event":"shipment.status","created_at":"2026-08-22T07:50:22+00:00","sandbox":false,
 "data":{"shipment_id":22771,"reference":"RAP709034","status":"In Warehouse","total_usd":36,"weight":4,"comment":"Received at warehouse","at":"…"}}

Answer 2xx within 15 seconds. Anything else is retried at 1, 5, 25, 125… minutes up to 6 attempts; an endpoint that fails 25 deliveries in a row is switched off until you resume it. Deliveries are at-least-once — use id to de-duplicate.

Try It