---
title: "Create tracking request"
method: POST
path: "/trackings"
tags: ["Tracking"]
---

# Create tracking request

`POST /trackings`

## Request

- Base URL: `https://parcelsapp.com/api-docs/mock/v4`
- URL: `https://parcelsapp.com/api-docs/mock/v4/trackings`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/parcelsapp/apis/parcels-api-v4/docs/trackings/post.ts> (a function with typed inputs; its response is checked against the schema)

Creates a tracking request for packages, postal parcels, express shipments, freight references, containers, or air waybills. Use the same `tracking_number` field for all of them; Parcels detects the best carrier route automatically. For reliable air waybill detection, submit `NNN-NNNNNNNN` with the hyphen after the airline prefix and preserve leading zeros.

Quota is counted by unique `tracking_number` within the current billing cycle. Re-submitting the same tracking number during that cycle does not consume another shipment from the monthly quota.

The response always includes `request_id` and `expires_at`. A request is an asynchronous lookup result, not a persistent shipment subscription; it is eligible for deletion about 30 minutes after its last update. Re-POST the same tracking number whenever you need a later refresh. If Parcels already has fresh cached data, the matching result is returned immediately with `from_cache: true`. If every requested shipment is cached, `done` is `true` and polling is optional. If only part of the request is cached, cached results are returned immediately and the remaining results stay in `state: processing` until polling or webhooks complete.

`destination_country` accepts an ISO-2 country code such as `US` or a full English country name such as `United States`. It is required for ordinary parcel/package numbers, but not required when `carrier_hint` is provided or when the tracking number is an air waybill, ISO container number, or recognized ocean bill of lading.

For carrier-specific recipient or shipment details, use `postal_code`, `email`, `phone`, and the documented `additional_fields` keys. `GET /tracking-carriers` publishes verified requirements using these exact request paths. Unknown or malformed `additional_fields` reject only the affected shipment. These values are used for the lookup and are not returned as interactive prompt events.

Pass `webhook_url` to receive callbacks for this request. A `batch_completed` webhook is also sent when the whole request is served from cache. Webhooks do not keep monitoring the shipment after that request completes; schedule a new POST with `webhook_url` for each later check. The create response returns a webhook secret once; store it and verify future `Parcels-Signature` headers.

## Request body

- CreateTrackingRequest: Starts one asynchronous lookup. For continuous monitoring, create another request on your schedule; repeating a tracking number within the same billing cycle does not consume another unique-shipment quota unit.
  - `language` string: Response language. Defaults to `en`.
  - `webhook_url` string, uri: Optional HTTPS endpoint for signed completion callbacks for this request only. This does not create a persistent shipment subscription; include the URL again in each later POST.
  - `shipments` TrackingItem[], required
    - `tracking_number` string, required: Any parcel, package, freight, container, or air waybill tracking number. For air waybills, use `NNN-NNNNNNNN` with a hyphen after the three-digit airline prefix and preserve leading zeros; unhyphenated 11-digit numbers may not match the intended cargo carrier.
    - `destination_country` string: ISO-2 country code or full English country name. Required for ordinary parcel/package numbers. Not required when `carrier_hint` is provided or when `tracking_number` is an air waybill, ISO container number, or recognized ocean bill of lading.
    - `carrier_hint` string: Optional carrier slug when you already know the carrier and want to skip broad auto-detection. Discover supported tracking slugs with `GET /tracking-carriers`; `GET /carriers` is reserved for delivery-estimate carrier/mode discovery.
    - `postal_code` string: Recipient postal code. For SEUR, provide this together with the recipient email or phone registered with SEUR. Check the carrier's `input_requirements` in `GET /tracking-carriers` when one has been published.
    - `email` string, email: Recipient email address, used only when the selected carrier needs recipient identification. For SEUR, supply this or the recipient phone together with destination postal_code. Use the address registered with SEUR, not the API account address.
    - `phone` string: Recipient phone number when accepted by the selected carrier as an alternative identifier. For SEUR, supply this or recipient email together with destination postal_code.
    - `additional_fields` TrackingAdditionalFields: Carrier-specific lookup input. Supply carrier_hint with the matching slug and only its fields published in GET /tracking-carriers. Values are non-empty strings of at most 256 characters; unsupported keys, mismatched carriers, or invalid values reject that shipment with INVALID_ADDITIONAL_FIELDS. Dole vessel and voyage must be supplied together. These values are used for the carrier lookup; interactive input prompts are omitted from API tracking events.
      - `house_number` string: Recipient house or street number for trans-o-flex, together with postal_code.
      - `bc_code` string: JRS Express 3 or 4 digit BC verification code for a separate airbill number.
      - `address_key` string: Gebrüder Weiss shipper or consignee address key. postal_code can be used instead when it is the carrier's address key.
      - `consignee_info` string: Additional consignee input requested by Gebrüder Weiss when the address key alone does not resolve the order.
      - `customer_token` string: Noerpel customer login token, supplied with postal_code.
      - `vessel` string: Dole Ocean Cargo vessel name for container lookups; send together with voyage.
      - `voyage` string: Dole Ocean Cargo voyage number for container lookups; send together with vessel.

## Response `200`

Tracking request created. Results can be completed from cache or still processing.

- TrackingResponse: One asynchronous lookup result. `request_id` can be polled until completion and remains readable only until approximately `expires_at`; create a new request for later monitoring.
  - `request_id` string, required: Identifier for this asynchronous lookup result, not a shipment identifier or persistent monitoring subscription.
  - `status` 'processing' | 'completed', required
  - `done` boolean, required
  - `expires_at` string, date-time, required: Expected retention boundary for this `request_id`, about 30 minutes after the request's last update. It is not a delivery deadline. GET may return 404 after this time; re-POST the tracking number for a later carrier check.
  - `results` TrackingResult[], required
    - `tracking_number` string, required
    - `state` 'processing' | 'completed', required
    - `from_cache` boolean, required: True when Parcels returned fresh cached data immediately instead of starting a new carrier request.
    - `shipment` Shipment
      - `trackingId` string
      - `error` string: Terminal shipment-level tracking error. `ADDITIONAL_FIELDS_REQUIRED` means a carrier such as SEUR needs more recipient identification to complete the lookup; this does not confirm that the tracking number exists. Inspect `input_requirements` to see required fields and alternatives, then retry with valid recipient details. `TIMEDOUT` means Parcels stopped waiting for a stale in-progress request and returned a final result instead of leaving the request processing forever.
      - `accepted_fields` string[]: For `ADDITIONAL_FIELDS_REQUIRED`, API v4 shipment item fields accepted for a retry. Consult `input_requirements` for which fields are required and which are alternatives.
      - `input_requirements` TrackingInputRequirements: Published input rule for a carrier. Absent when a complete rule has not been verified; absence does not promise that no recipient fields are needed. Required fields must be supplied together with at least one any_of field when both lists are present.
        - `required` TrackingInputFieldName[]: Fields to provide for every lookup.
        - `any_of` TrackingInputFieldName[]: Provide at least one of these fields in addition to required fields.
        - `conditional` TrackingInputFieldName[]: The carrier may require these fields for some shipments. Check the carrier-specific instructions for fields that must be supplied together.
      - `status` string
      - `origin` string
      - `destination` string
      - `originCode` string
      - `destinationCode` string
      - `transportMode` 'parcel' | 'postal' | 'express' | 'road_freight' | 'air_cargo' | 'ocean_container': Concrete transport mode. Forecast fallback never crosses this boundary.
      - `fromAirport` string: Origin IATA airport code when explicitly provided for an air-cargo shipment.
      - `toAirport` string: Destination IATA airport code when explicitly provided for an air-cargo shipment.
      - `fromPort` string: Origin UN/LOCODE when explicitly provided for an ocean shipment.
      - `toPort` string: Destination UN/LOCODE when explicitly provided for an ocean shipment.
      - `pieces` number: Shipment piece count when supplied by the carrier.
      - `weight` number: Shipment weight when supplied by the carrier.
      - `weight_unit` string: Unit for `weight`.
      - `volume` number: Shipment volume when supplied by the carrier.
      - `volume_unit` string: Unit for `volume`.
      - `flight_legs` FlightLeg[]: Carrier-supplied air-cargo routing legs. Schedule fields are kept separate from booking/milestone event timestamps and omitted when the carrier does not supply them.
        - `flight_number` string
        - `origin` string: Flight-leg origin IATA code.
        - `destination` string: Flight-leg destination IATA code.
        - `status` string: Carrier-reported status of this leg.
        - `scheduled_departure_date` string, date: Scheduled departure date when the carrier supplies a date but no reliable time.
        - `scheduled_departure` string, date-time: Scheduled departure with the carrier station's offset.
        - `scheduled_arrival` string, date-time: Scheduled arrival with the destination station's offset.
        - `actual_departure` string, date-time: Actual departure confirmed by the carrier.
        - `actual_arrival` string, date-time: Actual arrival confirmed by the carrier.
        - `pieces` number
        - `weight` number
        - `weight_unit` string
        - `volume` number
        - `volume_unit` string
      - `states` TrackingEvent[]: Carrier tracking events. Interactive prompts asking for recipient fields are omitted from API responses and webhooks; when no real events are available this array can be empty.
        - `state` string
        - `location` string
        - `date` string, date-time: Carrier event time with its airport-local UTC offset when the carrier provides only local wall time.
        - `event_code` string: Carrier milestone code when supplied by the source.
        - `station` string: IATA station or airport code associated with the event.
        - `timezone` string: IANA time zone used to interpret the carrier-local event time.
        - `pieces` number: Pieces covered by this event, useful for partial movements.
        - `weight` number: Weight covered by this event when supplied by the carrier.
        - `weight_unit` string
        - `volume` number: Volume covered by this event when supplied by the carrier.
        - `volume_unit` string
        - `flight_number` string: Flight number associated with the event.
        - `flight_origin` string: IATA origin of the associated flight leg.
        - `flight_destination` string: IATA destination of the associated flight leg.
        - `scheduled_departure_date` string, date: Carrier-supplied scheduled flight date when no reliable scheduled departure time is available.
        - `scheduled_departure` string, date-time: Carrier-supplied scheduled departure, distinct from this event's `date`.
        - `scheduled_arrival` string, date-time: Carrier-supplied scheduled arrival for the flight leg.
        - `actual_departure` string, date-time: Confirmed actual departure for the associated flight leg when available.
        - `actual_arrival` string, date-time: Confirmed actual arrival for the associated flight leg when available.
        - `uld_number` string: Unit load device number associated with the event when supplied by the carrier.
        - `carrier` integer
      - `services` Carrier[]
        - `slug` string
        - `name` string
      - `detectedCarrier` Carrier
        - `slug` string
        - `name` string
      - `detected` integer[]
      - `attributes` ShipmentAttribute[]
        - `l` string
        - `val` string
        - `code` string
      - `externalTracking` ExternalTracking[]
        - `slug` string
        - `url` string
        - `trackingId` string
        - `method` string
    - `delivery_estimate` DeliveryEstimateResult
      - `client_reference` string
      - `carrier_slug` string, required
      - `transport_mode` 'parcel' | 'postal' | 'express' | 'road_freight' | 'air_cargo' | 'ocean_container', required: Concrete transport mode. Forecast fallback never crosses this boundary.
      - `completion_scope` 'carrier_acceptance_to_delivery' | 'airport_to_airport' | 'airport_to_availability' | 'port_to_port' | 'port_to_availability' | 'port_to_gate_out', required: Defines what event counts as completion, and therefore which historical durations are compared. It is not a transport phase or route precision setting. Most callers should omit it and use the mode default. In v1 the start is the earliest confirmed physical carrier event, such as acceptance, pickup, RCS, or origin-terminal gate-in. The `airport_*` and `port_*` names describe the route family and completion boundary; they do not guarantee that the first timestamp is a flight departure or vessel departure. | Value | Measured journey | | --- | --- | | `carrier_acceptance_to_delivery` | Physical carrier acceptance or pickup to delivered/POD. Default for `parcel`, `postal`, `express`, and `road_freight`. | | `airport_to_airport` | First confirmed physical air-cargo event (often pickup or RCS) to arrival received at the destination airport (usually RCF). Default for `air_cargo`. | | `airport_to_availability` | First confirmed physical air-cargo event to ready-for-collection/available at the destination airport. | | `port_to_port` | First confirmed physical ocean event, such as origin-terminal gate-in, to arrival/discharge at the destination port. Default for `ocean_container`. | | `port_to_availability` | First confirmed physical ocean event to available/released for pickup at the destination port. | | `port_to_gate_out` | First confirmed physical ocean event to gate-out or terminal handoff at destination; this is not delivery to a final street address. | Fallback never crosses a completion-scope boundary. If the selected scope lacks enough observations, the API returns `INSUFFICIENT_DATA` rather than using a different endpoint meaning.
      - `route_scope_used` string: Diagnostic name of the selected statistics bucket, including whether it is carrier specific or a mode fallback. Most integrations can ignore it.
      - `route` DeliveryEstimateRoute: Route-selection diagnostics. Most integrations can ignore this object.
        - `origin_dimension` 'city' | 'admin1' | 'country' | 'airport' | 'port', nullable
        - `origin_key` string, nullable
        - `destination_dimension` 'city' | 'admin1' | 'country' | 'airport' | 'port', nullable
        - `destination_key` string, nullable
        - `carrier_specific` boolean
      - `estimate` DeliveryEstimateValues
        - `mean_days` number, required: Arithmetic mean for analytics. Use median_days as the normal point estimate.
        - `median_days` number, required: Primary point estimate.
        - `typical_days` DeliveryEstimateRange, required: Typical P10-P90 range in calendar days.
          - `min` number
          - `max` number
        - `remaining_status` 'not_requested' | 'estimated' | 'insufficient_censored_data' | 'insufficient_tail_data', required: Whether remaining_days was not requested, safely estimated, or withheld. insufficient_censored_data means the right-censored risk set or identifiable tail is too small; insufficient_tail_data is the fail-closed completed-tail fallback used before a survival generation exists.
        - `remaining_days` DeliveryEstimateRemaining, nullable: Estimated days still remaining. The censored model requires at least 100 subjects, 30 completed events, cohort age of 120 days (300 for ocean), at least five journeys and 10% of subjects in the current risk set, and identifiable P10, P50, and P90. Otherwise remaining_status explains why the API withheld it.
          - `mean` number, nullable: Null for Kaplan-Meier output; use median, min, and max.
          - `median` number
          - `min` number
          - `max` number
        - `estimated_delivery_at` DeliveryEstimateWindow, nullable: Estimated UTC delivery window. Present only when the request supplied a start timestamp or usable elapsed duration.
          - `from` string, date-time
          - `to` string, date-time
      - `confidence` DeliveryEstimateConfidence: Quality of statistical support, not the probability of delivery on one promised date.
        - `level` 'low' | 'medium' | 'high', required: Simple evidence-quality label for normal integrations.
        - `score` number, required: Diagnostic evidence-quality score, not an on-time-delivery probability.
        - `sample_count` integer, required
        - `effective_sample_count` number, required
        - `remaining_effective_sample_count` number: For Kaplan-Meier, the right-censored risk-set size at elapsed time; for the completed-tail fallback, time-decayed completed-tail support. Present only for a progress request.
        - `minimum_remaining_effective_sample_count` number: Safety floor applied by the active remaining-time method. Kaplan-Meier requires at least five journeys and 10% of subjects in the risk set, in addition to the per-mode subject floor and identifiable P10-P90 tail.
        - `survival_subject_count` integer
        - `survival_completed_count` integer
        - `survival_censored_count` integer
        - `survival_risk_set` integer
        - `survival_minimum_subject_count` integer
        - `survival_minimum_completed_count` integer
        - `survival_cohort_age_days` number
        - `survival_minimum_maturation_days` integer
        - `lookback_days` integer, required
        - `last_observation_at` string, date-time, nullable
        - `freshness_days` number
        - `fallback_level` integer, required
      - `model` object: Model diagnostics for reproducibility. Most integrations can ignore this object.
        - `version` string
        - `unit` 'calendar_days'
        - `histogram_bucket_hours` integer
        - `remaining_method` 'kaplan_meier_right_censored_v1' | 'completed_tail_guard_v1': Kaplan-Meier uses active right-censored journeys and delayed entry. The completed-tail guard remains a fail-closed fallback when no survival generation is published.
      - `error` DeliveryEstimateInsufficientData
        - `code` 'INSUFFICIENT_DATA', required
        - `message` string, required
        - `available_sample_count` integer, required
        - `minimum_sample_count` integer, required
  - `rejected` RejectedShipment[]: Input items rejected during per-shipment validation. Other valid items in the same batch continue normally.
    - `index` integer, required: Zero-based index in the submitted shipments array.
    - `tracking_number` string: Trimmed tracking number from the submitted item, when it was a non-empty string.
    - `code` 'INVALID_TRACKING_NUMBER' | 'DESTINATION_COUNTRY_REQUIRED' | 'INVALID_ADDITIONAL_FIELDS', required
    - `message` string, required
  - `webhook` WebhookRegistration: Returned only in the create response when `webhook_url` is provided. The registration belongs to this request and ends when it completes; it does not monitor the shipment afterward. Store `secret`; it is not returned again.
    - `url` string
    - `secret` string
    - `signature_header` string

## Other responses

- `400`: Invalid request body, tracking number, destination country, or webhook URL.
- `401`: Missing or invalid API key.
- `402`: Subscription cannot currently create new tracking requests.
- `403`: Account cannot create tracking requests.
- `429`: Too many requests from this client.
- `500`: Unexpected server error.
- `503`: Tracking service is temporarily busy. The rejected request does not consume subscription quota.

## Changes

- **2026-11-06** `dd6315a8bc4e`: 15 warning, 30 info
  - added the new `INVALID_ADDITIONAL_FIELDS` enum value to the `error/rejected/items/code` response property for the response status `400`
  - added the new `INVALID_ADDITIONAL_FIELDS` enum value to the `error/rejected/items/code` response property for the response status `401`
  - added the new `INVALID_ADDITIONAL_FIELDS` enum value to the `error/rejected/items/code` response property for the response status `402`
  - added the new `INVALID_ADDITIONAL_FIELDS` enum value to the `error/rejected/items/code` response property for the response status `403`
  - …41 more
- **2026-07-19** `f8d02f819394`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/parcelsapp/apis/parcels-api-v4/changes/trackings/post.md)

---

[API](https://skmtc.dev/parcelsapp/apis/parcels-api-v4.md) - [All operations](https://skmtc.dev/parcelsapp/apis/parcels-api-v4/llms.txt) - [OpenAPI document](https://skmtc.dev/parcelsapp/apis/parcels-api-v4/revisions/dd6315a8bc4e?raw)
