Accurate Logistics API

Getting started

Send shipments to your shipping company straight from your store, ERP or website, and know the moment their status changes.

  1. Log in once to get a token.
  2. Create a shipment with one request.
  3. Get updates: we call your server on every status change, or you ask any time.

What you need

Ask your shipping company for:

Example
API address https://your-company.com:8443/graphql
Username and password of your customer account store@example.com

How requests work

Every request is a POST to that one address, with a JSON body. The body says what you want to do (query) and the values you send (variables). The API uses GraphQL, but you don't need to know it: copy the examples in this guide.

curl https://your-company.com:8443/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "query": "query ($code: String) { shipment(code: $code) { code status { name } } }",
    "variables": { "code": "A12345" }
  }'

The answer is always JSON. You get back exactly the fields you asked for.

Headers

Header Value
Content-Type application/json Required
Authorization Bearer YOUR_TOKEN Required, except to log in
Content-Language en or ar, the language of status and zone names Optional

Postman and Insomnia make testing easy: choose GraphQL as the body type, then paste the query and the variables from this guide.

Authentication

Log in once with your username and password to get a token, then send that token with every request.

Log in

mutation Login($input: LoginInput!) {
  login(input: $input) {
    token
  }
}

Use the token

Send it in the Authorization header of every request, after Bearer :

Text
Authorization: Bearer 3|kD8f2...x91

Keep the token on your server, like a password. Reuse it: log in again only when a request answers Unauthenticated.

Create a shipment

A shipment needs three ids: the shipping service, the recipient's zone (city) and subzone (area). Look them up once and save them in your system; they rarely change. Then creating a shipment is a single request.

1. Get the shipping services

query Services {
  listShippingServicesDropdown(input: { active: true }) {
    id
    name
  }
}

2. Get the zones and subzones

The zones the service delivers to:

query Zones($serviceId: Int!) {
  listZonesDropdown(input: { active: true, service: { serviceId: $serviceId } }) {
    id
    name
  }
}

Then the subzones inside a zone:

query Subzones($zoneId: Int!) {
  listZonesDropdown(input: { active: true, parentId: $zoneId }) {
    id
    name
  }
}

3. Create the shipment

mutation CreateShipment($input: ShipmentInput!) {
  saveShipment(input: $input) {
    id
    code
    trackingUrl
    status { code name }
  }
}

Save the id and code: you'll need them to track the shipment, and every webhook includes them.

Fields

Required

Field
serviceId Shipping service, from step 1
recipientZoneId, recipientSubzoneId Zone and subzone, from step 2
recipientMobile Recipient's mobile number
recipientAddress Full delivery address

Optional, most used

Field
refNumber Your order number. Recommended: you can search by it
recipientName, recipientPhone Name and a second number
price What the courier collects from the recipient (0 if prepaid)
priceTypeCode INCLD: price includes shipping fees · EXCLD: fees are added
paymentTypeCode COLC collect on delivery · PAID prepaid · more
typeCode FDP deliver (default) · PDP partial · PTP exchange · RTS pick up a return
openableCode Y / N: may the recipient open it before paying?
description, notes What's inside, and notes for the courier
weight, piecesCount, size Kilograms, pieces, { length, width, height } in cm
deliveryDate Requested date, YYYY-MM-DD
senderName, senderMobile, senderAddress, senderZoneId, senderSubzoneId Pickup details, if not your account's

Every field is in the reference.

To change a shipment, send saveShipment again with its id and the fields to change. That works until the shipping company starts handling it: the shipment's editable field tells you.

Track shipments

Prefer webhooks: we tell you as soon as a status changes, so you don't have to ask.

One shipment

query Track($code: String) {
  shipment(code: $code) {
    code
    refNumber
    status { code name }
    deliveredOrReturnedDate
    deliveredAmount
    trackingUrl
  }
}

status.code is one of the status codes; status.name is its name in the Content-Language you asked for.

Many shipments

query MyShipments($input: ListShipmentsFilterInput, $page: Int) {
  listShipments(input: $input, first: 50, page: $page) {
    paginatorInfo { currentPage lastPage total hasMorePages }
    data {
      code
      refNumber
      status { code name }
    }
  }
}

Up to 100 per page (first). Ask for the next page while hasMorePages is true.

Filters

Filter Example Finds
code ["A12345"] These shipment codes
refNumber ["ORDER-1001"] Your order numbers
search "01012345678" Part of the code, or a recipient's or sender's name or phone
statusCode ["DTR"] In these statuses
date { "fromDate": "2026-10-01" } Created in this period
deliveredOrReturnedDate { "fromDays": 7 } Delivered or returned in the last 7 days
delivered, notDelivered true Delivered, or not yet

All filters are in the reference.

Webhooks

Every time one of your shipments changes status, we send a POST to an address on your server. No need to keep asking.

  1. Make an address on your server that accepts a JSON POST, like https://your-store.com/accurate/webhook.
  2. Send it to your shipping company: they save it on your account.
  3. Answer 200 as soon as a request arrives, then update the shipment in your system.

What you receive

{
  "shipmentId": 10832354,
  "shipmentCode": "A12345",
  "typeCode": "SHP_STATUS_UPDATE",
  "shipmentStatusCode": "DTR",
  "deliveryTypeCode": "FD",
  "returnTypeCode": null,
  "deliveredAmount": 250,
  "collectedFees": 0,
  "deliveryDate": "2026-10-13",
  "cancellationReasonId": null,
  "notes": "Delivered to the security guard"
}
Field
shipmentId, shipmentCode The shipment, as saveShipment returned it
shipmentStatusCode The new status: see codes
deliveryTypeCode When delivered: FD fully, PD partially
returnTypeCode When returned: how the fees were settled, see codes
deliveredAmount Collected from the recipient
collectedFees Shipping fees collected from the recipient
deliveryDate Delivery date
cancellationReasonId Why it couldn't be delivered, if given
notes The courier's notes
typeCode Always SHP_STATUS_UPDATE
X-Client-Id header Your shipping company's name, if you work with several

Fields that don't apply to the status are null.

The same update can arrive twice. Saving the same status again should do no harm.

Codes

Shipment status

In the order a shipment usually goes through them.

Code Status Meaning
PKR Shipping request Created, waiting for pickup
PKM Picking up A courier is on the way to pick it up
PKH Pickup rescheduled Pickup will be tried again
PKD Picked up Picked up from you
RJCT Rejected Refused by the shipping company
RITS In the warehouse At the shipping company's warehouse
PRP Being prepared Being packed
PRPD Prepared Ready to go out
BMT Sent to another branch Moving between branches
BMR Arrived at the branch At the branch that delivers it
STD Handing to courier Being given to the delivery courier
OTD Out for delivery On the way to the recipient
DTR Delivered See deliveryTypeCode
DEX Delivery failed Not delivered this time, see cancellationReasonId
HTR Waiting to redeliver Will be delivered again later
RTS Returning Will come back to you
RCV Return in the warehouse Back at the warehouse
OTR Out for return On the way back to you
RTRN Returned Back with you, see returnTypeCode

Delivery type

Code
FD Fully delivered
PD Partially delivered: the rest comes back

Return type

Code
WODF Returned, you pay no fees
WFDF Returned, you pay the full shipping fees
WPDF Returned, you pay part of the shipping fees
FFC Returned, the recipient paid the full shipping fees
FPC Returned, the recipient paid part of the shipping fees
PRTS Partially returned

Shipment type

Code
FDP Deliver the whole package (default)
PDP The recipient may keep only part of it
PTP Exchange: deliver one package, bring another back
RTS Pick up a package from the recipient for you

Payment type

Code
COLC Collect from the recipient on delivery
PAID Prepaid
CASH Paid in cash
CRDT Postpaid, settled with you later
VISA Paid by card

Price type and open package

Code
INCLD price includes the shipping fees
EXCLD Shipping fees are added to price
Y The recipient may open the package before paying
N The recipient may not open it

Errors

A failed request has an errors list. The HTTP status is usually still 200, so always check for errors.

Response
{
  "errors": [
    {
      "message": "Validation failed for the field [saveShipment].",
      "extensions": {
        "validation": {
          "input.recipientMobile": ["The recipient mobile field is required."]
        }
      }
    }
  ],
  "data": { "saveShipment": null }
}
Message What to do
Unauthenticated. Log in again and retry
Validation failed… extensions.validation lists each wrong field and why
Variable "$input" got invalid value… A value has the wrong type, or a required field is missing
Value "X" does not exist in "…" enum Use one of the codes
Cannot query field "x"… Check the field's name in the reference
This action is unauthorized. Your account isn't allowed to: ask your shipping company

Send Content-Language: ar to get messages in Arabic. Log the whole errors list when a request fails: it makes support much faster.

What changed

If your integration follows an older version of these docs:

Change What to do
serviceId is required in saveShipment Send a service id from listShippingServicesDropdown
recipientPhone is optional Nothing: recipientMobile is still required
customerId in listShipments is a list Send [123] instead of 123
ImageInput.file is a required file upload Upload the file itself
ttl removed from login Stop asking for it
state, city, area removed from Branch Stop asking for them
Shipment type CLC removed Use another shipment type
ShipmentFees.post, tax and Shipment.createdBy may be null Handle an empty value
Webhooks also send shipmentCode Find the shipment by its code

API reference

Every operation and type available to your account. Click a type to jump to it.

Operations

Query listShipments

Arguments

NameType
input ListShipmentsFilterInput
first requiredInt!Limits number of fetched items. Maximum allowed value: 100.
page IntThe offset from which items are returned.

Returns ShipmentPaginator!

Query listShipmentTypesDropdown

Arguments

NameType
serviceId Int
mobileActive Boolean

Returns [DropdownEntry]

Query shipment

Arguments

NameType
id Int
code String

Returns Shipment

Types

Input BoxSizeInput

NameType
length requiredFloat!
width requiredFloat!
height requiredFloat!

Type Branch

NameType
idInt!
codeString!
nameString!
activeBoolean!
mainBoolean!
addressString
phoneString
faxString
countryCountry
warehouseSections[WarehouseSection]

Type Country

NameType
idInt!
codeString!
nameString!

Enum CustomerTypeCode

Customer type code

MERCHANT INDIVIDUAL CONCIERGE

Input DateFilterInput

NameType
fromDays Int
fromDate Date
toDate Date

Input DeliveryAgentCustodyInput

NameType
deliveryAgentId Int

Type DropdownEntry

NameType
idInt
codeString
nameString

Input FilterZonesByServiceInput

NameType
serviceId requiredInt!
customerId Int
customerTypeCode CustomerTypeCode
fromZoneId Int
fromSubzoneId Int

Type Image

NameType
pathString!
subjectCodeString

Input ImageInput

NameType
file requiredUpload!
subjectCode String

Input ListLookupEntriesFilterInput

NameType
code requiredString!

Input ListPaymentTypesDropdownInput

NameType
customerId Int

Input ListShipmentsFilterInput

NameType
id [Int]
code [String]
search String
refNumber [String]
typeCode ShipmentTypeCode
paymentTypeCode ShipmentPaymentTypeCode
customerTypeCode CustomerTypeCode
branchId Int
originBranchId Int
serviceId Int
customerId [Int]
userId Int
inDeliveryAgentCustody DeliveryAgentCustodyInput
senderZoneId [Int]
senderSubzoneId [Int]
recipientZoneId [Int]
recipientSubzoneId [Int]
date DateFilterInput
lastTransactionDate DateFilterInput
deliveredOrReturnedDate DateFilterInput
statusCode [ShipmentStatusCode]
deliveryTypeCode ShipmentDeliveryTypeCode
returnTypeCode ShipmentReturnTypeCode
pendingCustomerAdjusting Boolean
pendingCustomerPayment Boolean
notDelivered Boolean
collected Boolean
paid Boolean
delivered Boolean
inWarehouse Boolean
forUnpacking Boolean
pendingCollection Boolean
lastDeliveryAgentId Int
deliveryBefore Date
sectionId Int
hasProducts Boolean
new Boolean
cancelled Boolean
routeId [Int]

Input ListShippingServicesFilterInput

NameType
customerTypeCode CustomerTypeCode
customerId Int
active Boolean

Input ListZonesFilterInput

NameType
name String
parentId Int
countryId Int
branchId Int
active Boolean
service FilterZonesByServiceInput

Input LoginInput

NameType
username requiredString!
password requiredString!
rememberMe requiredBoolean!
fcmToken String

Type Lookup

NameType
idInt!
codeString!
nameString!
entries[LookupEntry]

Type LookupEntry

NameType
idInt!
codeString!
nameString!
activeBoolean
weightInt!
lookupLookup!
mobileActiveBoolean

Type PaginatorInfo

Information about pagination using a fully featured paginator.

NameType
countInt!Number of items in the current page.
currentPageInt!Index of the current page.
firstItemIntIndex of the first item in the current page.
hasMorePagesBoolean!Are there more pages after this one?
lastItemIntIndex of the last item in the current page.
lastPageInt!Index of the last available page.
perPageInt!Number of items per page.
totalInt!Number of total available items.

Type Permission

NameType
idInt!
nameString!
slugString!

Type Role

NameType
idInt!
codeString!
nameString!
usersCountInt!
permissions[Permission]!

Type Sequence

NameType
idInt!
codeString
nameString!

Type Shipment

NameType
idInt!
codeString!
typeLookupEntry!
openableLookupEntry!
dateDateTime!
createdAtDateTime!
updatedAtDateTime
deliveryDateDate
deliveredOrReturnedDateDateTime
descriptionString
weightFloat!
piecesCountInt!
collectedBoolean!
paidToCustomerBoolean!
paidToDeliveryAgentBoolean!
editableBoolean!
trackingUrlString!
deletableBoolean!
hasProductsBoolean!
inWarehouseBoolean!
unpackedBoolean!
refNumberString
notesString
adminNotesString
returnPiecesCountInt
paymentTypeLookupEntry!
priceTypeLookupEntry!
deliveryTypeLookupEntry
returnTypeLookupEntry
transactionTypeTransactionType!
branchBranch!
originBranchBranch!
statusLookupEntry!
returnStatusLookupEntry
serviceShippingService!
history[Shipment!]!
createdByUser
updatedByUser
warehouseSectionWarehouseSection
customerTypeLookupEntry!
attemptsInt
cancellableBoolean!
cancelledBoolean!
priceFloat!
amountFloat!
deliveryFeesFloat!
extraWeightFeesFloat!
collectionFeesFloat!
totalAmountFloat!
deliveredAmountFloat!
returningDueFeesFloat!
returnedValueFloat!
allDueFeesFloat!
collectedFeesFloat!
customerDueFloat!
collectedAmountFloat!
pendingCollectionAmountFloat!
returnFeesFloat!
postFeesFloat!
taxFloat!
deliveryCommissionFloat
recipientNameString
recipientPhoneString
recipientMobileString!
recipientZoneZone!
recipientSubzoneZone!
recipientAddressString!
recipientPostalCodeString
recipientLatitudeFloat
recipientLongitudeFloat
senderNameString
senderPhoneString
senderMobileString
senderZoneZone
senderSubzoneZone
senderAddressString
senderPostalCodeString
senderLatitudeFloat
senderLongitudeFloat
deliveryOtpString
hasDeliveryOtpBoolean!
images[Image]

Enum ShipmentDeliveryTypeCode

Shipment delivery type code

FD PD

Type ShipmentFees

NameType
amountFloat!
deliveryFloat!
weightFloat!
collectionFloat!
postFloat
taxFloat
returnFloat!
totalFloat!

Input ShipmentInput

NameType
id Int
code String
date DateTime
deliveryDate Date
serviceId requiredInt!
description String
refNumber String
weight Float
size BoxSizeInput
piecesCount Int
returnPiecesCount Int
price Float
notes String
typeCode ShipmentTypeCode
priceTypeCode ShipmentPriceTypeCode
paymentTypeCode ShipmentPaymentTypeCode
openableCode ShipmentOpenableCode
shipmentProducts [ShipmentProductInput]
senderName String
senderZoneId Int
senderSubzoneId Int
senderPhone String
senderMobile String
senderAddress String
senderPostalCode String
senderLatitude Float
senderLongitude Float
recipientName String
recipientZoneId requiredInt!
recipientSubzoneId requiredInt!
recipientPhone String
recipientMobile requiredString!
recipientAddress requiredString!
recipientLatitude Float
recipientLongitude Float

Enum ShipmentOpenableCode

Shipment openable code

Y N

Type ShipmentPaginator

A paginated list of Shipment items.

NameType
paginatorInfoPaginatorInfo!Pagination information about the list of items.
data[Shipment!]!A list of Shipment items.

Enum ShipmentPaymentTypeCode

Shipment payment type code

COLC PAID CASH CRDT VISA

Enum ShipmentPriceTypeCode

Shipment price type code

EXCLD INCLD

Input ShipmentProductInput

NameType
productId requiredInt!
price requiredFloat!
quantity requiredInt!
typeCode ShipmentProductTypeCode

Enum ShipmentProductTypeCode

Shipment product type code

IN OUT

Enum ShipmentReturnTypeCode

Shipment return type code

FFC FPC WFDF WODF WPDF PRTS

Enum ShipmentStatusCode

Shipment status code

PKR PKM PKH PKD RJCT BMR BMT PRP PRPD RITS STD OTD DTR DEX HTR RTS RCV OTR RTRN

Enum ShipmentTypeCode

Shipment type code

FDP PDP PTP RTS

Type ShippingService

NameType
idInt!
codeString!
nameString!
daysInt!
egsCodeString
activeBoolean!
branchBranch
shipmentTypes[LookupEntry]

Type UserBranch

NameType
userUser!
branchBranch!
defaultBoolean!

Type UserWithToken

NameType
userUser!
tokenString!

Type WarehouseSection

NameType
idInt!
nameString!
branchBranch!
activeBoolean!
shipments[Shipment]

Type Zone

NameType
idInt!
codeString!
nameString!
parentZone
activeBoolean
branchBranch
children[Zone]