← Plugin catalog
Developer Tools

Ship24 Tracking API

Ship24 Limited v1.0.0

Integrate shipment tracking

Create a free account to save this plugin.

From the developer

Not specified in the available declarations: capabilities, limitations, pricing & account requirements.

Onboarding example

How do I add Ship24 shipment tracking to my app?
Sources & dates

Developer declarations; not independently tested. Listing last checked Nov 12, 2026. Package observed Nov 11, 2026.

View package source →

Description

From the marketplace listing

Ship24 shipment tracking for AI coding agents. Guides you through integrating the Ship24 Tracking API into your own project end to end: every endpoint and schema from the OpenAPI spec, webhook receivers versus polling, courier codes and required fields, tracking status mapping, the official Node SDK, and error and rate-limit troubleshooting. Your code calls Ship24 with your own API key.

Language: English · Automatically detected from descriptions.

Matches for “app api”

Exact text from the indicated source. A mention alone does not establish support for your task.

Publisher full description

Ship24 shipment tracking for AI coding agents. Guides you through integrating the Ship24 Tracking API into your own project end to end: every endpoint and schema from the OpenAPI spec, webhook receivers versus polling, courier codes and required fields, tracking status mapping, the official Node SDK, and error and rate-limit troubleshooting. Your code calls Ship24 with your own API key.

Plugin name

Ship24 Tracking API

Publisher description

Ship24 shipment tracking for AI coding agents: skills to integrate the Ship24 Tracking API, build webhook receivers, look up courier codes, map tracking statuses and troubleshoot errors.

What changed

Keywords

Files & skills

File archives

Plugin package85 files · 219 KBBrowse files →
Skill instructions
ship24-couriers4.18 KB

View saved version →

---
name: ship24-couriers
description: Ship24 courier codes, courier auto-detection and per-courier required fields. Use when asked "which courier code for <carrier>", "force the courier", "does <carrier> need a postcode", "courier not detected", "courierCode", "list of couriers Ship24 supports", or when a tracker returns no results and the courier may be the cause. Explains when to send courierCode, the 3-per-request limit, requiredFields, deprecated codes, and how to fetch the courier list once and cache it instead of calling GET /couriers on every request.
license: MIT
---

# Courier codes and detection

Sources: [Couriers](https://docs.ship24.com/couriers) and the `GET /couriers` operation in the OpenAPI spec
(field table in `references/courier-fields.md`). The courier list itself is not bundled: it changes over time, and a
stale code is silently ignored by the API, so always read it from the live API.

## Auto-detection first

Ship24 detects the courier from the tracking number in most cases. `courierCode` is optional. Send it when:

- the user already knows the courier (it improves accuracy and avoids ambiguous matches);
- a tracker returned no results and the courier is a plausible cause;
- tracking must be restricted to specific couriers (`settings.restrictTrackingToCourierCode: true`).

Do not guess a code. If the courier is unknown, omit the field and let Ship24 detect it.

## Format and limits

| Rule | Value | Source |
| --- | --- | --- |
| Type | string or array of strings | OpenAPI `tracker-create-request` |
| Per request | up to 3 codes | Couriers page |
| Per shipment | up to 9 codes in total; `PATCH /trackers/{trackerId}` is the documented way to add codes afterward | Couriers and Trackers pages |
| Deprecated code (`isDeprecated: true`) | silently ignored, not rejected | Couriers page |
| `settings.restrictTrackingToCourierCode` | `true` pins tracking to the given codes only | OpenAPI |

`tracker_conflict` means a tracker with similar conflicting parameters already exists. Provide additional
parameters such as `shippingDate` or `destinationCountryCode` to differentiate it (see `ship24-troubleshooting`).

## Required fields per courier

Each courier entry carries `requiredFields`, a list of values that Ship24 needs to retrieve results for that
courier. Ship24 does not reject a request that omits them, but it may then fail to find the shipment.

| `requiredFields` value | Tracker field to send |
| --- | --- |
| `destinationPostCode` | `destinationPostCode` (1 to 32 chars) |
| `destinationCountryCode` | `destinationCountryCode` (ISO 3166-1 alpha-2 or alpha-3) |
| `courierAccount` | No matching request field exists in the spec today, so it cannot be supplied through the API. |

The dashboard CSV export exposes the same information as `is_destination_postcode_required`,
`is_destination_country_code_required`, `is_courier_account_required` columns.

## `courierCode` is not `sourceCode`

`courierCode` identifies the courier you ask Ship24 to track with (for example `us-post`). Event `sourceCode`
identifies the data source Ship24 obtained the event from (for example `usps-tracking`). They differ, and
source codes may evolve; never feed a `sourceCode` back as a `courierCode`.

## Getting the courier list

| Source | How | Notes |
| --- | --- | --- |
| Live API | `GET /couriers` or the `get_couriers` MCP tool | Full list, unpaginated, rate limit 1 request per second. Fetch once per session or deployment, cache it, never call it per request. |
| Dashboard | Integrations → Couriers, CSV download | Same data for humans. |

To answer "which code for <carrier>", fetch the list once and filter it locally on `courierName` and
`courierCode`; the response is large, so do not paste it whole into the conversation. Skip entries with
`isDeprecated: true`. `isPost` is `true` when the courier is a postal operator; `countryCode` is the courier's
main country and may be `null`.

Codes appearing in the OpenAPI examples: `us-post` (USPS)

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 4 — file references are metadata, not package contents.

ship24-integration11.3 KB

View saved version →

---
name: ship24-integration
description: Integrate the Ship24 Tracking API into a codebase end to end. Use when asked to "add Ship24", "integrate Ship24", "integrate package, parcel or shipment tracking", create trackers, choose between webhooks and polling, or call the per-call tracking endpoint, in any language or framework. Detects the project's stack, confirms the Ship24 plan type and update mechanism, then guides implementation and verification against the OpenAPI spec. For webhook receivers, courier codes, statuses, errors or the Node SDK, the sibling ship24-* skills go deeper.
license: MIT
---

# Ship24 Tracking API integration

Opinionated wizard: detect the project, clarify the plan, guide the implementation, verify the result.

Facts in this skill come from [docs.ship24.com](https://docs.ship24.com) and the OpenAPI 3.1 spec at
[docs.ship24.com/assets/openapi/ship24-tracking-api.yaml](https://docs.ship24.com/assets/openapi/ship24-tracking-api.yaml).
The bundled `references/endpoints.md` and `schemas.md` are generated from that spec, `errors.md` and
`rate-limits.md` from the docs pages. When a detail matters (a field name, a status
code, a limit), read the reference file rather than guessing:

| Need | Read |
| --- | --- |
| Every endpoint, parameters, responses, rate limit | `references/endpoints.md` |
| Field tables for tracker, tracking, shipment, event, request bodies | `references/schemas.md` |
| HTTP statuses and error codes | `references/errors.md` |
| Rate limits and rate-limit headers | `references/rate-limits.md` |
| Webhook vs polling trade-offs, matching records, idempotent creation | `references/integration-patterns.md` |

Sibling skills: `ship24-webhooks` (build the receiver), `ship24-couriers` (courier codes and required fields),
`ship24-tracking-statuses` (map statuses to business logic), `ship24-troubleshooting` (errors), `ship24-node-sdk`
(the official `ship24` npm package).

## Phase 1: Detect

Scan before asking. Use the host tool's search if there is no shell.

```bash
grep -ri "ship24" . --include=*.{js,ts,py,rb,php,go,java,cs,env,json,yaml,yml} 2>/dev/null | head -20
grep -ri "SHIP24" .env .env.local .env.example 2>/dev/null
grep -rE "express|fastify|nest|fastapi|django|flask|rails|laravel|symfony|gin|spring|aspnet" \
  package.json requirements.txt pyproject.toml Gemfile composer.json go.mod pom.xml *.csproj 2>/dev/null | head
grep -rn "webhook" . --include=*.{js,ts,py,rb,php,go,java,cs} 2>/dev/null | head
grep -rE "bull|bullmq|celery|sidekiq|rabbitmq|sqs|pubsub|kafka" \
  package.json requirements.txt pyproject.toml Gemfile composer.json go.mod 2>/dev/null | head -5
```

Note: existing Ship24 usage (trackers created? webhook route present?), language and framework, HTTP client in
use, queue or async infrastructure, an existing public webhook route that can be extended.

If the project is Node.js or TypeScript, prefer the official SDK (`npm install ship24`) over hand-written HTTP
calls and switch to the `ship24-node-sdk` skill for the implementation details.

## Phase 2: Clarify

Ask only what detection could not determine, one question at a time.

1. **Account and key.** Does the user have a Ship24 account and API key? A free plan exists for integration and
   testing: [dashboard.ship24.com/onboarding](https://dashboard.ship24.com/onboarding). Keys live under
   Integrations → API Keys (up to 20 active keys per account).
2. **Plan type.** Per-shipment (the standard product: trackers, webhooks, polling) or per-call (a separate
   subscription, one synchronous endpoint, no trackers)? If unsure: per-shipment is the default choice; Ship24
   documents it as offering more features, faster fetching and lower overall cost.
3. **Update mechanism** (per-shipment only). Webhooks (Ship24 pushes updates, recommended) or polling (the app
   calls the API)? Webhooks need a public HTTPS endpoint. At thousands of trackers, polling stops being
   practical.
4. **Constraints.** New project or existing app? Serv

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 8 — file references are metadata, not package contents.

ship24-node-sdk10.1 KB

View saved version →

---
name: ship24-node-sdk
description: Use the official Ship24 npm package in TypeScript or Node.js. Triggers include "Ship24 Node SDK", "ship24 npm package", "use ship24", "ship24.trackers.create", "import ship24", "new Ship24", or asking to replace hand-written fetch or axios calls to Ship24 in Node/TypeScript. Routes deeper Node SDK questions away from generic integration guidance. Covers installation, constructor configuration, all 12 endpoint methods, error handling, per-call vs per-shipment differences, pagination, and when retries are needed.
license: MIT
---

# Ship24 Node SDK

Official SDK for the Ship24 Tracking API. Full TypeScript support, zero runtime dependencies, native `fetch`.

## Install

```bash
npm install ship24
```

The SDK README lists Node 18+, Bun, Deno, Cloudflare Workers and modern browsers as supported runtimes; CI tests Node 20/22/24, Bun and Deno. Never ship a production API key to a browser: keep the SDK on the server. It ships ESM and CommonJS:

```ts
// ESM
import { Ship24 } from 'ship24';
// CommonJS
const { Ship24 } = require('ship24');
```

## Quickstart

```ts
import { Ship24 } from 'ship24';

const apiKey = process.env.SHIP24_API_KEY;
if (!apiKey) throw new Error('SHIP24_API_KEY is not set');

const ship24 = new Ship24({ apiKey });
const tracker = await ship24.trackers.create({ trackingNumber: '1234567890' });
console.log(tracker.trackerId);
```

## Configuration

Pass a `Ship24Config` object to the constructor. Only `apiKey` is required:

```ts
type Ship24Config = {
  apiKey: string; // required; the SDK does not read the environment itself
  baseUrl?: string; // default 'https://api.ship24.com'; the SDK appends /public/v1
  timeoutMs?: number; // see Timeouts
  fetch?: typeof fetch; // custom fetch implementation
  headers?: Record<string, string>; // extra default headers; Authorization is always overwritten
};
```

### Timeouts

Defaults are 10 seconds per request and 60 seconds for the synchronous `ship24.trackers.track` and `ship24.perCall.track` (Ship24 queries couriers synchronously, up to about a minute). In SDK 1.0.0 the constructor's `timeoutMs` is stored but never read by the transport, so set the timeout per call:

```ts
const result = await ship24.trackers.track(
  { trackingNumber: '1234567890' },
  { timeoutMs: 120_000 }
);
```

Per-call options are accepted by every method: `{ timeoutMs?, signal?, headers? }`. Tracker-id methods also accept `{ searchBy: 'trackerId' | 'clientTrackerId' }` to resolve the id as your own client id.

## Methods

See `references/sdk-methods.md` for the full table of 12 methods, their endpoints, signatures and when each is used, and `references/endpoints.md` for the endpoint paths, response codes and rate limits generated from the OpenAPI spec. Highlights:

### Per-shipment (default, recommended)

Create trackers, receive updates via webhooks or polling, manage courier codes.

```ts
await ship24.trackers.create({ trackingNumber, courierCode?, clientTrackerId? });
await ship24.trackers.track({ trackingNumber });  // sync, ~60s
await ship24.trackers.bulkCreate([{ trackingNumber }, ...]);  // up to 100
await ship24.trackers.list({ page?, limit?, sort? });
await ship24.trackers.get(trackerId);
await ship24.trackers.getResults(trackerId);
await ship24.trackers.update(trackerId, { isSubscribed? });
await ship24.trackers.resendWebhooks(trackerId);
await ship24.couriers.list();  // rate limited 1 req/s
```

### Per-call (separate subscription)

Synchronous one-off lookups; no persistent tracker.

```ts
await ship24.perCall.track({ trackingNumber, destinationCountryCode? });
```

Returns `PerCallTracking[]`. Note there is **no `.tracker`** field, unlike `trackers.track`.

## Error handling

All errors extend `Ship24Error`. Catch by class, then optionally branch on `code`:

```ts
import {
  Ship24Error,
  NotFoundError,
  RateLimitError,
  SubscriptionError,
  AuthenticationError,
  ValidationError,
  ConflictError,
  QuotaError,
  ServerError,
  Ship24Con

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 5 — file references are metadata, not package contents.

ship24-tracking-statuses6.22 KB

View saved version →

---
name: ship24-tracking-statuses
description: Map Ship24 tracking statuses to application logic using statusMilestone, statusCode and statusCategory. Use when asked "Ship24 status", "statusMilestone", "statusCode", "statusCategory", "is the parcel delivered", "terminal status", "notify the customer on status change", "sample tracking numbers", or when deciding which status field to store, filter or alert on. Covers the 8 milestones, 6 categories and 20 codes, event ordering, and the SHIP24_SAMPLE_* test numbers.
license: MIT
---

# Tracking statuses

Source: [Status](https://docs.ship24.com/status). The OpenAPI spec types these fields as plain strings and does
not encode the enums, so the docs table, mirrored in `references/statuses.md`, is the authoritative list.

## Three fields

| Field | Where | Meaning |
| --- | --- | --- |
| `statusMilestone` | every event, and at shipment level | Overall status of the shipment at that moment. Always present. |
| `statusCategory` | events | Category of the event (`data`, `transit`, `destination`, `customs`, `delivery`, `exception`). May be empty on non-significant events. |
| `statusCode` | events | Codified meaning of the event (20 values). May be empty on non-significant events. |
| `status` | events | Raw courier text, not normalized (for example `ENTREGADO. Su envío está entregado.`). Display it, never branch on it. |

For a high-level state use `shipment.statusMilestone`. For fine-grained triggers use `events[].statusCode`.

## Milestones

| `statusMilestone` | Label | Description (docs) | Typical handling |
| --- | --- | --- | --- |
| `pending` | Pending | The shipment doesn’t have events available yet or can’t be found. | Wait; if it persists, check the courier and required fields (`ship24-couriers`). |
| `info_received` | Info. Received | The shipment has been declared electronically and/or is in preparation by the shipper. | Show "label created". |
| `in_transit` | In Transit | The shipment has been accepted or picked up from the shipper and is on the way. | Default active state. |
| `out_for_delivery` | Out for Delivery | The shipment is about to be delivered, usually the same day. | Notify the recipient. |
| `failed_attempt` | Failed Attempt | A delivery attempt was made and failed (Recipient not available, business closed, etc.) | Notify; the courier usually retries or leaves the parcel at a pickup point. |
| `available_for_pickup` | To Pick Up | The shipment is ready to be picked up by the receiver. (At a pickup point such as a post office, a locker, or a local business) | Notify with urgency. |
| `delivered` | Delivered | The shipment has been delivered. (Delivered at home, picked up from a pickup point, etc.) | Close the flow. |
| `exception` | Exception | The shipment can’t be delivered due to issues that seem to be final (Returning, returned, lost, destroyed, etc.) | Open a support case. |

Ship24 documents no "terminal" flag. Trackers are disabled automatically after delivery, and `isTracked: false`
means tracking has stopped (delivery, inactivity or unsubscription). Stop polling on `isTracked`, not on a
status, and keep processing any webhook that still arrives.

## Categories and codes

Full table in `references/statuses.md`. Codes worth dedicated business rules:

| `statusCode` | Category | Meaning (docs) |
| --- | --- | --- |
| `delivery_delivered` | delivery | Shipment has been delivered. |
| `delivery_attempted` | delivery | Delivery attempted and unsuccessful. Usually, the delivery will be tried again the next day, or the shipment will be left at a pick-up point. |
| `delivery_available_for_pickup` | delivery | Shipment available for pickup at a pick-up point or at the Post Office. |
| `delivery_exception` | delivery | Issue during delivery or preventing delivery, which usually could be solved. |
| `delivery_refused` | delivery | Shipment refused by the recipient. |
| `customs_exception` | customs | Exception or delay during customs clearance. Additional docume

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 4 — file references are metadata, not package contents.

ship24-troubleshooting7.36 KB

View saved version →

---
name: ship24-troubleshooting
description: Diagnose Ship24 Tracking API problems from the symptom. Use when asked about a Ship24 error, a 400, 401, 403, 422 or 429 response, tracker_not_found, parcel_not_found, tracker_conflict, quota_limit_reached, "no tracking results", "tracker not updating", "webhook not received", "rate limited", or when the Ship24 MCP tools return 401 or seem to be missing. Gives the cause and the fix for every documented HTTP status and error code.
license: MIT
---

# Troubleshooting

Sources: [Error management](https://docs.ship24.com/errors), [Rate limiter](https://docs.ship24.com/rate-limiter),
[Standard data format](https://docs.ship24.com/data-format), [Trackers](https://docs.ship24.com/trackers),
[Integrate with AI](https://docs.ship24.com/integrate-with-ai). Full tables: `references/errors.md`,
`references/rate-limits.md`, `references/statuses.md`, `references/endpoints.md`.

Error bodies are `{ "errors": [{ "code", "message" }], "data": null }`; `message` is optional. `POST /trackers/bulk`
is the exception: its body is `{ status, summary, data, error }` with the code under `error.code`. Branch on
`code`; `message` is for humans and may change.

## Symptom to fix

| Symptom | Likely cause | Fix |
| --- | --- | --- |
| `401` | Missing or wrong `Authorization: Bearer apik_...` header, revoked key | Check the header and the key in Dashboard → Integrations → API Keys. |
| `403` | Insufficient permissions or endpoint limitations; on `POST /trackers/bulk` it carries `quota_limit_reached` | Check the subscription and quota in the dashboard. A missing plan for an endpoint answers `422` + `no_active_subscription` instead. |
| `400` + `validation_error` | A field failed validation | Read `message`. Country codes: ISO 3166-1 alpha-2 or alpha-3, uppercase. Tracking number: 5 to 50 chars, `A-Z a-z 0-9 - _ / .`, dummy values rejected. Postcode: 1 to 32 chars, `A-Z a-z 0-9 - _ / .` and space. |
| `400` + `tracker_conflict` | A tracker with similar conflicting parameters already exists: the `clientTrackerId` belongs to an active tracker with a different payload, or (on `POST /trackers/track`) the `courierCode` list overlaps an existing tracker's list without matching it | Provide additional parameters such as `shippingDate` and `destinationCountryCode` to differentiate the tracker, or resend the identical payload to reuse it. |
| `bulk_create_limit_exceeded` | More than 100 items in `POST /trackers/bulk` (bulk envelope, code under `error.code`) | Split into batches of 100. |
| `402` | Parameters valid but the request failed | Read the error `code`; it names the reason. |
| `404` + `tracker_not_found` | Unknown `trackerId`, or `clientTrackerId` used without `searchBy=clientTrackerId` | Check the id and the `searchBy` query parameter. |
| `409` + `request_conflict` | Same payload sent in parallel; one request won | Retry later; idempotent endpoints are safe to retry. |
| `400` + `shipping_date_outdated` | `shippingDate` older than 180 days | Ship24 does not track shipments older than 6 months. |
| `422` + `no_active_subscription` | No subscription covers the endpoint, most often `POST /tracking/search` without a per-call plan | Use the per-shipment endpoints (`POST /trackers/track` for a synchronous lookup) or subscribe. |
| `quota_limit_reached` | Trackers or calls above the plan's quota for the billing period | Wait for the period to reset or upgrade. Note that changed payloads create new trackers and consume quota. |
| `tracker_not_updatable` | The shipment has already been processed; courier and destination can only change while Ship24 has found no trace of it | Create a new tracker with the corrected data. |
| `parcel_not_found` | Shipment created recently and not yet visible at the courier, or too little information | Wait and retry; add `originCountryCode`, `destinationCountryCode`, `destinationPostCode`, `shippingDate` when known. Do not add made-up destination fields to sample numbers. |
| `processing_

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 7 — file references are metadata, not package contents.

ship24-webhooks7.51 KB

View saved version →

---
name: ship24-webhooks
description: Build a correct Ship24 webhook receiver in any language. Use when asked to receive Ship24 tracking updates, build a webhook endpoint, verify webhook secrets, handle tracking or proof of delivery webhooks, or test webhook delivery. Covers authentication, payload structure, retry logic, ordering guarantees, and best practices to avoid data loss and duplicate processing.
license: MIT
---

# Building Ship24 webhook receivers

Ship24 pushes tracking events to your system via webhooks instead of requiring you to poll. Your webhook endpoint must validate the authentication, answer quickly, and process messages idempotently.

Facts in this skill come from [docs.ship24.com/webhooks](https://docs.ship24.com/webhooks/overview) and the Ship24 implementation verified on 2026-09-09. When implementing, consult:

| Need | Resource |
| --- | --- |
| Payload structure and field names | `references/webhook-payloads.md` (generated from the OpenAPI spec) and the example payloads under `assets/` |
| Event statuses and milestones | `ship24-tracking-statuses` skill |
| Error codes | `ship24-troubleshooting` skill |
| Receiver code examples | `references/receiver-checklist.md` (Express, FastAPI, Rails) |
| Testing your receiver | `ship24-webhook-test` skill |

Sibling skills: `ship24-integration` (full integration workflow), `ship24-webhook-test` (test your receiver), `ship24-tracking-statuses` (map status codes to business logic), `ship24-troubleshooting`.

## Configuration

**Webhook URL**: Dashboard only. Log in to [dashboard.ship24.com](https://dashboard.ship24.com), go to Integrations → Webhooks, and set your HTTPS endpoint. Optional: set a separate Proof of Delivery Webhook URL if you have the PoD add-on. The dashboard test button does NOT originate from the documented outgoing IP.

**Webhook secret (authentication)**: Each account has one shared secret sent as `Authorization: Bearer <secret>` in every request.

- It is NOT an HMAC signature; there is no per-message signature or replay protection.
- Compensate by using HTTPS, constant-time comparison of the secret (e.g., `crypto.timingSafeEqual`, `secrets.compare_digest`, `ActiveSupport::SecurityUtils.secure_compare`), whitelisting the outgoing IP `54.161.7.2`, and deduplicating on `metadata.messageId` and `events[].eventId`.

## Payload structure: tracking events

Ship24 sends tracking results under topic `tracking/events`:

```json
{
  "trackings": [{
    "metadata": {"generatedAt": "2025-03-04T17:13:35.000Z", "messageId": "...", "topic": "tracking/events"},
    "tracker": {"trackerId": "...", "trackingNumber": "...", "shipmentReference": "...", "clientTrackerId": "...", "isSubscribed": true, "createdAt": "..."},
    "shipment": {"shipmentId": "...", "statusMilestone": "delivered", "statusCode": "delivery_delivered"},
    "events": [{"eventId": "...", "status": "...", "occurrenceDatetime": "2025-03-04T17:12:57", "order": 9, "statusMilestone": "delivered"}],
    "statistics": {"timestamps": {...}}
  }]
}
```

**Structure:**
- Root key is `trackings` (array); each item has metadata, tracker (webhook-tracker, no `isTracked`/`courierCode`), shipment, events array (always exactly one event per webhook item), statistics.
- Match shipments on `tracker.trackerId` (preferred) or `tracker.clientTrackerId`.
- `metadata.topic` is `tracking/events` or `tracking/pod`.
- Add-on fields (e.g., `shipment.delivery.aiPredictiveDeliveryDate`) are absent, not `null`, when unavailable. Check field presence before reading.

## Payload structure: proof of delivery

Set a separate Proof of Delivery Webhook URL in the dashboard (if you have the PoD add-on). Payloads contain `metadata`, `tracker`, and `data` with fields: `status` (`found` or `unavailable`), `courier` (source code), `content.type` (text/plain, text/html, application/pdf, image/png, image/jpeg), `content.downloadUrl` (valid 7 days, download immediately). PoD payloads are never grouped; `trackings` always has exactly o

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 7 — file references are metadata, not package contents.

ship24-webhook-test7.63 KB

View saved version →

---
name: ship24-webhook-test
description: Test and debug a Ship24 webhook receiver end to end. Use when asked to test your webhook, simulate tracking updates, replay webhook messages, run a local webhook receiver, or validate webhook handling. Provides a runnable HTTP server and walkthrough for creating sample shipments, triggering events, and auditing delivery.
license: MIT
---

# Testing Ship24 webhooks end to end

Verify your receiver handles tracking updates correctly before going to production.

## Quick start

### 1. Start a local receiver

From the installed skill directory (wherever your tool placed `ship24-webhook-test`), or from a clone of https://github.com/ship24/ship24-ai-plugin:

```bash
cd skills/ship24-webhook-test
node scripts/receiver.mjs
```

Output:

```
Ship24 webhook test receiver listening on http://localhost:3000 (POST any path)
secret check: off (set SHIP24_WEBHOOK_SECRET to enable); log: stdout
```

The receiver:
- Accepts `POST` on any path.
- Responds `200 { ok: true }` immediately.
- Logs to stdout (or a file if `LOG_FILE` is set).
- Validates the `Authorization: Bearer <secret>` header if `SHIP24_WEBHOOK_SECRET` is set.
- No external dependencies; uses Node 22 built-in `node:http`.

**Env variables:**

- `PORT`: Listen port (default 3000).
- `SHIP24_WEBHOOK_SECRET`: Optional. When set, rejects requests whose `Authorization` header does not match using a constant-time comparison.
- `LOG_FILE`: Optional. Append NDJSON logs to a file instead of stdout.

### 2. Expose to the internet

Ship24 must reach your receiver. Use any tunnel you already have; examples:

- **ngrok**: `ngrok http 3000`
- **Cloudflare Tunnel**: `cloudflared tunnel --url http://localhost:3000`
- **LocalTunnel**: `npx localtunnel --port 3000`

Note the public HTTPS URL the tunnel prints.

### 3. Configure the dashboard

1. Log in to [dashboard.ship24.com](https://dashboard.ship24.com)
2. Go to Integrations → Webhooks
3. Paste the public URL into the Webhook URL field
4. Copy the Webhook Secret and set it locally:

```bash
export SHIP24_WEBHOOK_SECRET=your_webhook_secret
```

5. (Optional) Test using the dashboard button. This test does not originate from the documented outgoing IP `54.161.7.2`, so it is blocked if you restrict by IP.

### 4. Create a sample tracker

Use one of the bundled MCP tools, the Node SDK, or a direct HTTP call:

**Via MCP (if available):**

```
create_tracker trackingNumber=SHIP24_SAMPLE_DELIVERED_000
```

**Via Node SDK:**

```javascript
import { Ship24 } from 'ship24';

const client = new Ship24({ apiKey: process.env.SHIP24_API_KEY });
const tracker = await client.trackers.create({
  trackingNumber: 'SHIP24_SAMPLE_DELIVERED_000'
});
console.log('Tracker:', tracker.trackerId);
```

**Via curl:**

```bash
curl -X POST https://api.ship24.com/public/v1/trackers \
  -H "Authorization: Bearer $SHIP24_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"trackingNumber": "SHIP24_SAMPLE_DELIVERED_000"}'
```

Sample tracking numbers:

- `SHIP24_SAMPLE_DELIVERED_000` - Delivered
- `SHIP24_SAMPLE_IN_TRANSIT_000` - In transit
- `SHIP24_SAMPLE_EXCEPTION_000` - Exception
- Change the last three digits to mint a fresh tracker with the same event sequence (e.g., `SHIP24_SAMPLE_DELIVERED_123`).

### 5. Watch deliveries

As you create the tracker, Ship24 discovers events and sends webhooks. Check your receiver logs:

```
{"timestamp":"2025-03-04T17:13:02.114Z","method":"POST","path":"/","authorization":"Bearer [masked]","topic":"tracking/events","messageId":"...","trackerId":"...","trackingNumber":"SHIP24_SAMPLE_DELIVERED_000","statusMilestone":"delivered","eventId":"...","statusCode":"delivery_delivered","occurrenceDatetime":"2025-03-04T17:12:57"}
```

### 6. Replay with resend

To replay all webhooks for a tracker (useful if you dropped messages):

**Via MCP:**

```
resend_webhooks trackerId=<trackerId>
```

**Via curl:**

```bash
curl -X POST https://api.ship24.com/public/v1/trackers/<trackerId>/webhook-events/rese

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 7 — file references are metadata, not package contents.

Package details

Publisher declarations from the archived package. These are separate from our research and the live service's terms.

Package license
MIT
Package author
Ship24
Keywords
See keywords

Package observed Nov 11, 2026.

Technical details
First seen
Sep 30, 2026 · 22:02 UTC
Last seen
Nov 12, 2026 · 06:00 UTC
Collection status
Collected

plugins_6aace9b25cc8819185620a8407053ddb

Download plugin data (JSON)

Plugin details: served from cache. Prepared . Refreshed when plugin data changes or after 6 hours. Your account and Follow status are live.