lastscanned Webhooks API

The Webhooks API from lastscanned — 6 operation(s) for webhooks.

Operations 10

POST /v1/watches Watch numbers #
GET /v1/watches List watches #
GET /v1/watches/{id} Get a watch #
DELETE /v1/watches/{id} Stop watching #
GET /v1/webhook Get the webhook #
PUT /v1/webhook Set the webhook #
DELETE /v1/webhook Remove the webhook #
POST /v1/webhook/test Send a test event #
GET /v1/webhook/deliveries Delivery log #
POST /v1/webhook/deliveries/{id}/retry Send a delivery again #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/lastscanned-com:lastscanned-com-webhooks-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

lastscanned-com-webhooks-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: lastscanned Webhooks API
  version: '1'
  description: 'Package tracking across 542 carriers: UPS, USPS, DHL, FedEx, Amazon Logistics, OnTrac, UniUni, GOFO, Veho, Spee-Dee, CDL Last Mile, Better Trucks, AxleHire (Jitsu), CIRRO, Yanwen, 4PX, Cainiao, YunExpress, SpeedX, Intelcom, Canada Post, Purolator, TForce Final Mile, GLS US, OSM Worldwide, Pitney Bowes, CNE Express, SunYou, UBI Smart Parcel, Sendle, Asendia, Japan Post, SingPost, Korea Post, NZ Post, DPD UK, APC Postal Logistics, Landmark Global, Canpar, Loomis Express, GLS Canada, Nationex, bpost, PostNord, Austrian Post, Poczta Polska, GLS, InPost, Packeta, Hermes Germany, YDH, Equick China, TopYou, La Poste, PostNL, Correos, Poste Italiane, CJ Logistics, Yamato Transport, Delhivery, Blue Dart, Evri, An Post, Swiss Post, BRT, Aramex Australia, CouriersPlease, Team Global Express, Ninja Van, Flash Express, ICS Courier, Chit Chats, Passport, ePost Global, JYExpress, Sagawa Express, Aramex, T-cat, Hanjin, Lotte Global Logistics, Logen, Shadowfax, SFC, Anjun, Winit, NZ Couriers, Post Haste, Castle Parcels, Gaopost, YF Express, GDWSE, Chronopost, Bring, Posti, Česká pošta, CTT, SEUR, Nova Poshta, Sameday, FAN Courier, Econt, Meest, Yurtiçi Kargo, Paquetexpress, Andreani, The Courier Guy, PostNet, 99minutos, Mainfreight, YTO Express, SPL Saudi Post, KEX Express, Pos Malaysia, GDEX, City-Link Express, LBC Express, DHL eCommerce, DHL Parcel NL, DHL Parcel Iberia, DHL Parcel PL, DHL eCommerce UK, DHL Freight, DHLink, XQ Express, Ali Business Logistics, Omniva, Ukrposhta, Speedy, DPD Romania, DPD Poland, DPD, DPD Portugal, Thailand Post, Chunghwa Post, EMS, ELTA, Estafeta, Total Express, Sagawa Global, MRW, Nacex, HuaHan, Chukou1, ZTO International, STO Express, OCA, OCASA, Coordinadora, HCT Logistics, Starken, Hunter Express, Aras Kargo, SMSA Express, Naqel Express, AUS Express, BDTPost, Boyi Hongda, BYT Logistics, CD International, CHH Logistics, Chuangyu Logistics, DHFEX, EDL Express, ED POST, ETSCP, Fuhai Wulian, FJEX, JSH Galaxy Express, ASGYL, Tianhai Supply Chain, YouMeiYuTong, HLSZ56, HOYANG Express, Heping Logistics, HSD Express, JTEX, PD Express, Jiuhao International, JDT Logistics, LeiYi Logistics, Lingdong International, Mayi Yinfu, Miuson Express, Pingda International, PY Express, QFL Express, QYEXP, Qyun Express, Shang Fang International, SHSGEXP, StarGlobal, TDE Logistics, Tianhui Hengyuan, Usky Express, WM Cloud, XS Express, YJI Logistics, Yilong Logistics, Yincag Logistics, ESHUN, ACS Courier, Airpak Express, Allegro One, Anteraja, AyMakan, Cargus, CDEK, Correos Express, CTT Express, DAI Post, ECMS Express, Ecoscooting, Geis, Jeebly, DHL eCommerce Türkiye, Northline, Nova Global, OMGO, Pakistan Post, Paperfly, Pathao Courier, PHLPost, Planzer, Pos Indonesia, Posta Shqiptare, Pošta Slovenije, PostEx, Pósturinn, Pro Carrier, PTS Worldwide Express, Quantium Solutions, Qwintry, Redur, RedX, South African Post Office, Seino Transportation, Sendex, Sending, Serpost, Servientrega, Shipa, ShipEntegra, Shree Maruti Courier, SkyNet Worldwide Express, SkyPostal, Speedaf, SpeedPAK, PostNL (Spring GDS), Slovak Parcel Service, SPX Express Indonesia, SPX Express Malaysia, SPX Express Philippines, SPX Express Thailand, SPX Express Vietnam, Stallion Express, Starex, ST Courier, Straightship, Swiss Post Cargo, TIPSA, TMM Express, TNT, TOPTRANS, TracX Logis, TWS Express Courier, Urvaam, Valmo, Vasp Expresso, Venipak, Vinted Go, Vozovoz, Zeleris, ZR Express, 4-72, Kuehne+Nagel, MailPlus, Amerijet, Matkahuolto, NOEST Express, 17FEIA, 2GO Express, 4Sides, 5Post, A1 POST, ABF Freight, A.'
servers:
- url: https://api.lastscanned.com
security:
- bearerAuth: []
- apiKeyHeader: []
tags:
- name: Webhooks
paths:
  /v1/watches:
    post:
      operationId: createWatch
      tags:
      - Webhooks
      summary: Watch numbers
      description: 'Looks the numbers up now and returns each watch with its current `result`, then re-checks them on a schedule and

        POSTs to the account''s webhook whenever the status, newest event or estimate changes. A new watch counts as a

        tracked number; re-checks are free. A number already being watched keeps its watch (200 instead of 201).'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                trackingNumber:
                  type: string
                trackingNumbers:
                  type: array
                  items:
                    type: string
                  maxItems: 100
                carrier:
                  $ref: '#/components/schemas/CarrierId'
                metadata:
                  type: object
                  description: Any JSON object under 2 KB
                  echoed in every event. `tag` (a string) is sent as 17TRACK's `tag`.: null
            example:
              trackingNumber: '541270563758'
              metadata:
                order: A1
      responses:
        '201':
          description: The watch (or `{watches}` for `trackingNumbers`), with its first result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Watch'
        '200':
          description: Already watched; the existing watch.
        '400':
          $ref: '#/components/responses/UnknownCarrier'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
    get:
      operationId: listWatches
      tags:
      - Webhooks
      summary: List watches
      parameters:
      - name: active
        in: query
        schema:
          type: boolean
          default: true
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 50
      - name: cursor
        in: query
        schema:
          type: string
      responses:
        '200':
          description: Watches, newest first.
          content:
            application/json:
              schema:
                type: object
                properties:
                  watches:
                    type: array
                    items:
                      $ref: '#/components/schemas/Watch'
                  nextCursor:
                    type:
                    - string
                    - 'null'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /v1/watches/{id}:
    parameters:
    - name: id
      in: path
      required: true
      schema:
        type: string
    get:
      operationId: getWatch
      tags:
      - Webhooks
      summary: Get a watch
      responses:
        '200':
          description: The watch with its last result or error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Watch'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      operationId: deleteWatch
      tags:
      - Webhooks
      summary: Stop watching
      responses:
        '200':
          description: '`{id, active: false, endReason: deleted}`'
        '404':
          $ref: '#/components/responses/NotFound'
  /v1/webhook:
    get:
      operationId: getWebhook
      tags:
      - Webhooks
      summary: Get the webhook
      responses:
        '200':
          description: The webhook.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
    put:
      operationId: setWebhook
      tags:
      - Webhooks
      summary: Set the webhook
      description: Sets the URL and/or format. The signing secret is made on first use and kept when the URL changes; `rotateSecret` makes a new one.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  format: uri
                  description: An https URL.
                format:
                  type: string
                  enum:
                  - lastscanned
                  - 17track
                rotateSecret:
                  type: boolean
            example:
              url: https://example.com/hooks/tracking
              format: lastscanned
      responses:
        '200':
          description: The webhook.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '400':
          description: Not an https URL
          or an unknown format.: null
    delete:
      operationId: deleteWebhook
      tags:
      - Webhooks
      summary: Remove the webhook
      responses:
        '200':
          description: The webhook
          now without a URL.: null
  /v1/webhook/test:
    post:
      operationId: testWebhook
      tags:
      - Webhooks
      summary: Send a test event
      responses:
        '200':
          description: What the endpoint answered.
          content:
            application/json:
              schema:
                type: object
                properties:
                  delivered:
                    type: boolean
                  status:
                    type:
                    - integer
                    - 'null'
                  error:
                    type:
                    - string
                    - 'null'
  /v1/webhook/deliveries:
    get:
      operationId: listDeliveries
      tags:
      - Webhooks
      summary: Delivery log
      description: Webhook deliveries from the last 30 days, newest first.
      parameters:
      - name: state
        in: query
        schema:
          type: string
          enum:
          - delivered
          - pending
          - failed
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 50
      - name: cursor
        in: query
        schema:
          type: string
      responses:
        '200':
          description: Deliveries.
          content:
            application/json:
              schema:
                type: object
                properties:
                  deliveries:
                    type: array
                    items:
                      $ref: '#/components/schemas/Delivery'
                  nextCursor:
                    type:
                    - string
                    - 'null'
  /v1/webhook/deliveries/{id}/retry:
    post:
      operationId: retryDelivery
      tags:
      - Webhooks
      summary: Send a delivery again
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: The delivery, queued to send.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Delivery'
        '404':
          $ref: '#/components/responses/NotFound'
components:
  schemas:
    ErrorBody:
      type: object
      required:
      - code
      - message
      properties:
        code:
          type: string
          enum:
          - bad_request
          - unknown_carrier
          - unauthorized
          - free_lookup_used
          - payment_required
          - credits_used
          - not_found
          - rate_limited
          - internal_error
          - not_configured
          - carrier_error
        message:
          type: string
    CarrierId:
      type: string
      description: Supported carrier identifier (`ontrac` covers LaserShip; `axlehire` covers Jitsu; `amazon` covers Amazon Logistics / MCF).
      enum:
      - ups
      - usps
      - dhl
      - fedex
      - amazon
      - ontrac
      - uniuni
      - gofo
      - veho
      - speedee
      - cdl
      - bettertrucks
      - axlehire
      - cirro
      - yanwen
      - 4px
      - cainiao
      - yunexpress
      - speedx
      - intelcom
      - canadapost
      - purolator
      - tforce
      - glsus
      - osm
      - pitneybowes
      - cne
      - sunyou
      - ubi
      - sendle
      - asendia
      - japanpost
      - singpost
      - koreapost
      - nzpost
      - dpduk
      - apc
      - landmark
      - canpar
      - loomis
      - glscanada
      - nationex
      - bpost
      - postnord
      - austrianpost
      - polishpost
      - gls
      - inpost
      - packeta
      - hermesde
      - ydh
      - equick
      - topyou
      - laposte
      - postnl
      - correos
      - posteitaliane
      - cjlogistics
      - yamato
      - delhivery
      - bluedart
      - evri
      - anpost
      - swisspost
      - brt
      - aramexau
      - couriersplease
      - teamglobalexpress
      - ninjavan
      - flashexpress
      - icscourier
      - chitchats
      - passport
      - epostglobal
      - jyexpress
      - sagawa
      - aramex
      - tcat
      - hanjin
      - lotte
      - logen
      - shadowfax
      - sfc
      - anjun
      - winit
      - nzcouriers
      - posthaste
      - castleparcels
      - gaopost
      - yfexpress
      - gdwse
      - chronopost
      - bring
      - posti
      - ceskaposta
      - ctt
      - seur
      - novaposhta
      - sameday
      - fancourier
      - econt
      - meest
      - yurtici
      - paquetexpress
      - andreani
      - thecourierguy
      - postnet
      - minutos99
      - mainfreight
      - yto
      - spl
      - kex
      - posmalaysia
      - gdex
      - citylink
      - lbc
      - dhlecommerce
      - dhlparcelnl
      - dhlparceles
      - dhlparcelpl
      - dhlecommerceuk
      - dhlfreight
      - dhlink
      - xqexpress
      - alibusiness
      - omniva
      - ukrposhta
      - speedy
      - dpdro
      - dpdpl
      - dpd
      - dpdpt
      - thailandpost
      - chunghwapost
      - ems
      - elta
      - estafeta
      - totalexpress
      - sagawaglobal
      - mrw
      - nacex
      - huahan
      - chukou1
      - ztointl
      - sto
      - oca
      - ocasa
      - coordinadora
      - hct
      - starken
      - hunterexpress
      - aras
      - smsa
      - naqel
      - asusexp
      - bdtpost
      - byhd
      - byt
      - chengda
      - chunhong
      - cyexpress
      - dhfex
      - edlexpress
      - edpost
      - etscp
      - fuhai618
      - fujexp
      - galaxyex
      - gdasgyl
      - gzbtygj
      - gzymyt
      - hlsz56
      - hoyang
      - hpgjwl
      - hsdex
      - hzjtex
      - hzpdex
      - jhgj
      - jiudt
      - leiyi
      - lingdong
      - mayiyinfu
      - miuson
      - pingda56
      - pyexpress
      - qfl
      - qyexp
      - qyun
      - shangfang
      - shsgexp
      - starglobal
      - sztdgyl
      - thhy
      - usky
      - wmycc
      - xsexp
      - yanjin
      - yilong
      - yincag
      - eshun
      - acscourier
      - airpakexpress
      - allegroone
      - anteraja
      - aymakan
      - cargus
      - cdek
      - correosexpress
      - cttexpress
      - daipost
      - ecms
      - ecoscooting
      - geis
      - jeebly
      - mngkargo
      - northline
      - novaglobal
      - omgo
      - pakistanpost
      - paperfly
      - pathao
      - phlpost
      - planzer
      - posindonesia
      - postashqiptare
      - postaslovenije
      - postex
      - posturinn
      - procarrier
      - ptsexpress
      - quantium
      - qwintry
      - redur
      - redx
      - sapo
      - seino
      - sendex
      - sending
      - serpost
      - servientrega
      - shipa
      - shipentegra
      - shreemaruti
      - skynetworldwide
      - skypostal
      - speedaf
      - speedpak
      - springgds
      - sps
      - spxid
      - spxmy
      - spxph
      - spxth
      - spxvn
      - stallionexpress
      - starex
      - stcourier
      - straightship
      - swisspostcargo
      - tipsa
      - tmmexpress
      - tnt
      - toptrans
      - tracxlogis
      - twsexpress
      - urvaam
      - valmo
      - vaspexpresso
      - venipak
      - vintedgo
      - vozovoz
      - zeleris
      - zrexpress
      - 472
      - kuehnenagel
      - mailplus
      - amerijet
      - matkahuolto
      - noest
      - 17feia
      - 2go
      - 4sides
      - 5post
      - a1post
      - abffreight
      - aduiepyle
      - aexparaguay
      - aitworldwide
      - ajex
      - amhomedelivery
      - ampm
      - anserx
      - apcovernight
      - appleexpress
      - aramexnz
      - atuhoraexpress
      - bangladeshpost
      - bexexpress
      - bjshomedelivery
      - blueex
      - blueexpress
      - bombino
      - bookurier
      - mrlglobal
      - borderexpress
      - bosta
      - boxnow
      - bringerparcel
      - bulgarianposts
      - burddelivery
      - c3x
      - cacesa
      - castores
      - ccfs
      - centraltransport
      - cevalogistics
      - chazki
      - chilexpress
      - chronodiali
      - ciblex
      - cityexpressrs
      - citymail
      - cjpacket
      - closerlogistics
      - colisweb
      - connectcouriers
      - copacourier
      - correoargentino
      - correosmexico
      - correossalvador
      - correouruguayo
      - couriercenter
      - cserussia
      - cypruspost
      - danskefragtmaend
      - daylighttransport
      - dayross
      - daytonfreight
      - dellin
      - gaash
      - dexpress
      - direx
      - dobropost
      - domainlogistics
      - domex
      - dpdza
      - dpex
      - dragonstarcurier
      - drop2shop
      - dropp
      - dsv
      - earlybird
      - easymail
      - egyptpost
      - ekart
      - emile
      - emsvietnam
      - enviacolombia
      - envialia
      - estes
      - euroexpressba
      - evdemo
      - evropat
      - ewe
      - exelot
      - exline
      - exmate
      - expressone
      - fargouz
      - fastfrate
      - fedexfreight
      - fedexpl
      - fermopoint
      - firstline
      - flashexpressph
      - fleetex
      - fleetoptics
      - flippost
      - followmont
      - forwardair
      - forzadelivery
      - foxpost
      - franchexpress
      - genikitaxydromiki
      - globalpost
      - glsfr
      - glsit
      - gmsworldwide
      - go4
      - gobolt
      - goexpress
      - gofofr
      - gofoit
      - gofonl
      - gogoxpress
      - grandslamexpress
      - gspostbox
      - gtaairskip
      - gtlgoto
      - happypost
      - haypost
      - helthjem
      - hepsijet
      - hermesat
      - hispapost
      - hongkongpost
      - hovership
      - hrparcel
      - hrvatskaposta
      - hywl
      - ilyanglogis
      - imile
      - indahlogistik
      - integralpack
      - internetexpress
      - interrapidisimo
      - israelpost
      - jandtau
      - jandtcargo
      - jandtde
      - janio
      - jcex
      - jdlogistics
      - jerseypost
      - jetlinecouriers
      - jetlogistic
      - jne
      - jsexpress
      - jumppoint
      - kazpost
      - kexexpresshk
      - kunexpress
      - kunyoung
      - kyoungdong
      - kyrgyzpost
      - laarcourier
      - labaih
      - laposteburkinafaso
      - lapostesenegal
      - lastonemilecoop
      - leopardscourier
      - liccardi
      - lietuvospastas
      - lightningexpress
      - lineclear
      - linhan
      - lionparcel
      - logistiq
      - lpost
      - madhurcourier
      - mailamericas
      - maltapost
      - maritimeontario
      - mauritiuspost
      - microexpress
      - midlandtransport
      - mone
      - mulphilog
      - mylerz
      - nextleveldelivery
      - nimexpress
      - nox
      - ocsana
      - olvacourier
      - oneworldexpress
      - orlenpaczka
      - paack
      - packlink
      - packman
      - pcpexpress
      - pdnexpress
      - pdqchile
      - pfcexpress
      - pilotfreight
      - pittohio
      - postamk
      - postluxembourg
      - ppl
      - precisiondeliveries
      - proships
      - pullmancargo
      - quiqup
      - raben
      - ramh2h
      - relaiscolis
      - rlcarriers
      - roadrunner
      - rpxindonesia
      - saia
      - sailpost
      - sapxexpress
      - satukraine
      - seko
      - shreeanjani
      - skroutzlastmile
      - skyking
      - slovenskaposta
      - southeasternfreightlines
      - speedandsafe
      - speedex
      - spxbr
      - sundarbancourier
      - tanzaniaposts
      - taxydema
      - tciexpress
      - tcspakistan
      - tdn
      - tealca
      - teamexpressae
      - teamworldwide
      - teleship
      - tfmexpress
      - tgroup
      - tirupaticourier
      - tntit
      - torrestir
      - trackon
      - transcorp
      - tstcfexpress
      - tufesa
      - uniteddeliveryservice
      - upaya
      - urbano
      - uzbekistanpost
      - veloces
      - viacargo
      - vimenpaq
      - vrllogistics
      - whistl
      - xdelogistics
      - xlcourier
      - xpoltl
      - ycslogistics
      - yunda
      - dohrn
      - horoz
      - dao
      - morningglobal
      - jordanpost
      - chinapost
      - gati
      - zajil
    TrackingEvent:
      type: object
      required:
      - timestamp
      - localTime
      - status
      - description
      - location
      - code
      properties:
        timestamp:
          type:
          - string
          - 'null'
          description: UTC, ISO 8601 with `Z`. `null` when the carrier gave no time of day or no zone to convert from.
          example: '2026-08-07T21:17:14Z'
        localTime:
          type:
          - string
          - 'null'
          description: The time as the carrier printed it, ISO 8601 with no zone. A date alone means no time of day was given.
          example: '2026-08-07T16:17:00'
        status:
          $ref: '#/components/schemas/TrackingStatus'
        description:
          type: string
        location:
          type:
          - string
          - 'null'
        code:
          type:
          - string
          - 'null'
          description: The carrier's own event code (every carrier but USPS).
    Watch:
      type: object
      properties:
        id:
          type: string
          example: wat_109060ade9f9a48732117f7a
        trackingNumber:
          type: string
        carrier:
          type:
          - string
          - 'null'
        status:
          oneOf:
          - $ref: '#/components/schemas/TrackingStatus'
          - type: 'null'
        active:
          type: boolean
        metadata:
          type:
          - object
          - 'null'
        createdAt:
          type: string
        checkedAt:
          type:
          - string
          - 'null'
        nextCheckAt:
          type:
          - string
          - 'null'
        endedAt:
          type:
          - string
          - 'null'
        endReason:
          type:
          - string
          - 'null'
          enum:
          - delivered
          - returned
          - not_found
          - expired
          - deleted
          - null
        result:
          oneOf:
          - $ref: '#/components/schemas/TrackingResult'
          - type: 'null'
        error:
          oneOf:
          - $ref: '#/components/schemas/ErrorBody'
          - type: 'null'
    Webhook:
      type: object
      properties:
        url:
          type:
          - string
          - 'null'
        secret:
          type:
          - string
          - 'null'
          description: 'Signs every request: `Lastscanned-Signature: t=<unix>,v1=<HMAC-SHA256 of "t.body">`.'
        format:
          type: string
          enum:
          - lastscanned
          - 17track
    TrackingResult:
      type: object
      required:
      - carrier
      - trackingNumber
      - status
      - statusDescription
      - service
      - deliveredAt
      - signedBy
      - destination
      - events
      properties:
        carrier:
          $ref: '#/components/schemas/CarrierId'
        trackingNumber:
          type: string
        status:
          $ref: '#/components/schemas/TrackingStatus'
        statusDescription:
          type: string
        service:
          type:
          - string
          - 'null'
        deliveredAt:
          type:
          - string
          - 'null'
          description: UTC, like `events[].timestamp`.
        deliveredAtLocal:
          type:
          - string
          - 'null'
          description: The delivery time as the carrier printed it, no zone.
        signedBy:
          type:
          - string
          - 'null'
        destination:
          type:
          - object
          - 'null'
          properties:
            city:
              type:
              - string
              - 'null'
            state:
              type:
              - string
              - 'null'
            country:
              type:
              - string
              - 'null'
        estimatedDelivery:
          type:
          - string
          - 'null'
          description: Expected delivery as local time with no zone, often a date only.
        estimatedDeliveryAt:
          type:
          - string
          - 'null'
          description: The same moment in UTC, only when the carrier states its zone (FedEx, DHL).
        message:
          type:
          - string
          - 'null'
          description: The carrier's own latest-update sentence, e.g. why a delivery is delayed or which carrier a cross-border parcel was handed to.
        events:
          type: array
          description: Newest first.
          items:
            $ref: '#/components/schemas/TrackingEvent'
    Delivery:
      type: object
      properties:
        id:
          type: string
          example: evt_63e401d5f73a4c31ef8fa8d9
        type:
          type: string
          enum:
          - tracking.updated
          - watch.ended
        trackingNumber:
          type: string
        watchId:
          type: string
        state:
          type: string
          enum:
          - delivered
          - pending
          - failed
        attempts:
          type: integer
        lastStatus:
          type:
          - integer
          - 'null'
        lastError:
          type:
          - string
          - 'null'
        createdAt:
          type: string
        deliveredAt:
          type:
          - string
          - 'null'
        failedAt:
          type:
          - string
          - 'null'
        nextAttemptAt:
          type:
          - string
          - 'null'
    TrackingStatus:
      type: string
      enum:
      - label_created
      - in_transit
      - out_for_delivery
      - delivered
      - exception
      - returned
      - unknown
    Error:
      type: object
      required:
      - error
      properties:
        error:
          $ref: '#/components/schemas/ErrorBody'
  responses:
    NotFound:
      description: '`not_found`: the carrier has no record of the number, or no such key.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: not_found
              message: UPS returned no track details for that number
    RateLimited:
      description: '`rate_limited`: the account''s daily limit is reached (resets 00:00 UTC), or the carrier is throttling (Spee-Dee).'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: rate_limited
              message: Daily limit of 5 tracking numbers reached; it resets at 00:00 UTC
    Unauthorized:
      description: '`unauthorized`: missing, wrong or revoked key, or a disabled account.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: unauthorized
              message: Invalid API key
    UnknownCarrier:
      description: '`unknown_carrier`: no carrier''s format matches the number (or its check digit is wrong), or `carrier` isn''t supported.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: unknown_carrier
              message: No carrier's format matches that tracking number (or its check digit is wrong); pass ?carrier=
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: '`Authorization: Bearer lsk_live_…`'
    apiKeyHeader:
      type: apiKey
      in: header
      name: x-api-key
      description: '`x-api-key: lsk_live_…`'