> ## Documentation Index
> Fetch the complete documentation index at: https://developers.teleship.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Register webhook endpoint

> Register a new webhook endpoint to receive real-time notifications about shipping events.

## Overview

Webhooks allow you to receive real-time updates about shipping events directly to your application. When events occur in your Teleship account, we'll send HTTP POST requests to your webhook endpoint with event data.

## How it works

1. **Register your endpoint** - Provide your URL and select which events to subscribe to
2. **Receive events** - Teleship sends HTTP POST requests to your endpoint when events occur
3. **Verify signatures** - Use the webhook secret to verify requests come from Teleship
4. **Process events** - Handle the event data in your application

## Payload Structure

All webhook payloads follow a consistent structure:

```json
{
  "eventName": "label.generated",
  "objectType": "shipment",
  "objectId": "6f384ad7-f8bf-40ce-8bf0-715248738f10",
  "data": {
    // Event-specific data (see examples below)
  }
}
```

### Payload Fields

- **eventName**: The type of event that occurred (e.g., "label.generated", "shipment.updated")
- **objectType**: The type of object this event relates to (e.g., "shipment", "manifest")
- **objectId**: The unique identifier of the object (e.g., shipment ID, manifest ID)
- **data**: The event-specific data payload

## Security & Signature Verification

### Webhook Secret

Each webhook endpoint has a unique secret that's only returned when you create the webhook. This secret is used to verify that webhook requests come from Teleship.

**Important**: The secret remains the same for the lifetime of the webhook unless you regenerate it.

### Signature Header

Teleship includes a signature in the `x-teleship-signature` header with every webhook request. Verify this signature to ensure the request is authentic:

```javascript
// Example signature verification
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}
```

## Event Types

### Available Events

- **`*`**: Subscribe to all events (default)
- **`label.generated`**: When a shipping label is created
- **`shipment.updated`**: When shipment status or details change
- **`manifest.created`**: When a manifest is created
- **`document.uploaded`**: When documents are uploaded

### Event Data Structure

The `data` field contains event-specific information. For shipment events, this includes:

```json
{
  "status": "label_created",
  "shipmentId": "6f384ad7-f8bf-40ce-8bf0-715248738f10",
  "trackingNumber": "TSGBUSA54UHK092337564",
  "customerReference": "#1001",
  "shipDate": "2025-06-30T22:36:22.843Z",
  "estimatedDelivery": "2025-07-08T06:59:59.999Z",
  "events": [
    {
      "timestamp": "2025-06-30T22:26:25.201Z",
      "code": "S_102",
      "description": "Shipment info received by carrier",
      "location": "London, UK"
    }
  ],
  "shipFrom": {
    "name": "London Store",
    "company": "TELESHIP LIMITED",
    "address": {
      "line1": "Flat 4, 24 Upper Tachbrook Street",
      "city": "London",
      "state": "England",
      "country": "GB",
      "postcode": "SW1V 1SW"
    }
  },
  "shipTo": {
    "name": "Fanny Dadin",
    "email": "fanny@teleship.com",
    "phone": "+1 213-601-6000",
    "address": {
      "line1": "1300 Eunice Avenue",
      "city": "Los Angeles",
      "state": "CA",
      "country": "US",
      "postcode": "90001"
    }
  },
  "firstMile": {
    "carrier": "DHL Express",
    "trackingNumber": "1234567890",
    "trackingUrl": "https://www.dhl.com/track/1234567890"
  },
  "lastMile": {
    "carrier": "USPS",
    "trackingNumber": "9400100000000000000000",
    "trackingUrl": "https://tools.usps.com/go/TrackConfirmAction?tLabels=9400100000000000000000"
  }
}
```

## Important Details

### Events Array

The `events` field is an **array** containing the complete event history for the shipment, not just the most recent event. Each event includes:
- **timestamp**: When the event occurred (UTC timezone)
- **code**: Event code from the carrier
- **description**: Human-readable event description
- **location**: Where the event occurred (if available)

### ObjectId and ObjectType

- **objectId**: The unique identifier of the shipment, manifest, or other object this event relates to
- **objectType**: The type of object ("shipment", "manifest", etc.)

These fields help you identify which specific object the event relates to in your system.

### Timezone

All timestamps in webhook payloads are in **UTC timezone** (ISO 8601 format). Convert to your local timezone as needed.

### FirstMile and LastMile

The `firstMile` and `lastMile` objects contain external carrier tracking information:

- **firstMile**: Information about the pickup/departure carrier
- **lastMile**: Information about the final delivery carrier

These fields are only populated when:
- The shipment uses multiple carriers (e.g., international shipments)
- External tracking numbers are available
- The carriers provide tracking URLs

The events in the `events` array come from both first-mile and last-mile carriers, providing a complete picture of the shipment's journey.

## Best Practices

1. **Verify signatures** - Always verify the webhook signature to ensure authenticity
2. **Handle duplicates** - Webhooks may be sent multiple times; use event IDs to prevent duplicate processing
3. **Respond quickly** - Return a 2xx status code immediately, then process the event asynchronously
4. **Handle failures gracefully** - Implement retry logic for failed webhook processing
5. **Monitor webhook health** - Track webhook delivery success rates and response times

## Example Implementation

```javascript
// Express.js webhook handler example
app.post('/webhooks/teleship', express.raw({type: 'application/json'}), (req, res) => {
  const signature = req.headers['x-teleship-signature'];
  const payload = req.body;

  // Verify signature
  if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(400).send('Invalid signature');
  }

  // Parse payload
  const event = JSON.parse(payload);

  // Handle different event types
  switch (event.eventName) {
    case 'label.generated':
      handleLabelGenerated(event.data);
      break;
    case 'shipment.updated':
      handleShipmentUpdated(event.data);
      break;
    default:
      console.log('Unhandled event type:', event.eventName);
  }

  // Respond quickly
  res.status(200).send('OK');
});
```

## Why use webhooks?

- **Real-time updates**: Get instant notifications when shipment status changes
- **Automation**: Trigger workflows based on shipping events
- **Integration**: Sync shipment data with your order management system
- **Customer experience**: Update customers with real-time tracking information
    



## OpenAPI

````yaml /api-reference/openapi.json post /api/webhooks
openapi: 3.0.0
info:
  title: Teleship
  description: >

    Teleship is a leading cross-border logistics provider offering seamless
    global commerce solutions through our comprehensive API.


    With Teleship's API, developers can integrate our cross-border shipping
    services, trade engine, and logistics solutions directly into their
    applications.


    **Key Features:**

    - Cross-border shipping solutions for international commerce

    - Real-time shipping rates and delivery estimates

    - End-to-end shipment tracking with detailed status updates

    - Automated customs compliance and product classification

    - Real-time event notifications through webhooks


    **Why Teleship?**

    - API-first: Developer-friendly integration with comprehensive documentation

    - Enterprise-ready: Built for businesses of all sizes

    - Secure: Enterprise-grade security and compliance

    - Integrated: Seamless connection with e-commerce, ERP, and fulfillment
    systems


    Start shipping globally with Teleship's powerful cross-border logistics API.
  version: 1.0.0
  contact: {}
servers:
  - url: https://api.teleship.com
security: []
tags: []
paths:
  /api/webhooks:
    post:
      tags:
        - Shipping Services
      summary: Register webhook endpoint
      description: >-
        Register a new webhook endpoint to receive real-time notifications about
        shipping events.


        ## Overview


        Webhooks allow you to receive real-time updates about shipping events
        directly to your application. When events occur in your Teleship
        account, we'll send HTTP POST requests to your webhook endpoint with
        event data.


        ## How it works


        1. **Register your endpoint** - Provide your URL and select which events
        to subscribe to

        2. **Receive events** - Teleship sends HTTP POST requests to your
        endpoint when events occur

        3. **Verify signatures** - Use the webhook secret to verify requests
        come from Teleship

        4. **Process events** - Handle the event data in your application


        ## Payload Structure


        All webhook payloads follow a consistent structure:


        ```json

        {
          "eventName": "label.generated",
          "objectType": "shipment",
          "objectId": "6f384ad7-f8bf-40ce-8bf0-715248738f10",
          "data": {
            // Event-specific data (see examples below)
          }
        }

        ```


        ### Payload Fields


        - **eventName**: The type of event that occurred (e.g.,
        "label.generated", "shipment.updated")

        - **objectType**: The type of object this event relates to (e.g.,
        "shipment", "manifest")

        - **objectId**: The unique identifier of the object (e.g., shipment ID,
        manifest ID)

        - **data**: The event-specific data payload


        ## Security & Signature Verification


        ### Webhook Secret


        Each webhook endpoint has a unique secret that's only returned when you
        create the webhook. This secret is used to verify that webhook requests
        come from Teleship.


        **Important**: The secret remains the same for the lifetime of the
        webhook unless you regenerate it.


        ### Signature Header


        Teleship includes a signature in the `x-teleship-signature` header with
        every webhook request. Verify this signature to ensure the request is
        authentic:


        ```javascript

        // Example signature verification

        const crypto = require('crypto');


        function verifyWebhookSignature(payload, signature, secret) {
          const expectedSignature = crypto
            .createHmac('sha256', secret)
            .update(JSON.stringify(payload))
            .digest('hex');

          return crypto.timingSafeEqual(
            Buffer.from(signature),
            Buffer.from(expectedSignature)
          );
        }

        ```


        ## Event Types


        ### Available Events


        - **`*`**: Subscribe to all events (default)

        - **`label.generated`**: When a shipping label is created

        - **`shipment.updated`**: When shipment status or details change

        - **`manifest.created`**: When a manifest is created

        - **`document.uploaded`**: When documents are uploaded


        ### Event Data Structure


        The `data` field contains event-specific information. For shipment
        events, this includes:


        ```json

        {
          "status": "label_created",
          "shipmentId": "6f384ad7-f8bf-40ce-8bf0-715248738f10",
          "trackingNumber": "TSGBUSA54UHK092337564",
          "customerReference": "#1001",
          "shipDate": "2025-06-30T22:36:22.843Z",
          "estimatedDelivery": "2025-07-08T06:59:59.999Z",
          "events": [
            {
              "timestamp": "2025-06-30T22:26:25.201Z",
              "code": "S_102",
              "description": "Shipment info received by carrier",
              "location": "London, UK"
            }
          ],
          "shipFrom": {
            "name": "London Store",
            "company": "TELESHIP LIMITED",
            "address": {
              "line1": "Flat 4, 24 Upper Tachbrook Street",
              "city": "London",
              "state": "England",
              "country": "GB",
              "postcode": "SW1V 1SW"
            }
          },
          "shipTo": {
            "name": "Fanny Dadin",
            "email": "fanny@teleship.com",
            "phone": "+1 213-601-6000",
            "address": {
              "line1": "1300 Eunice Avenue",
              "city": "Los Angeles",
              "state": "CA",
              "country": "US",
              "postcode": "90001"
            }
          },
          "firstMile": {
            "carrier": "DHL Express",
            "trackingNumber": "1234567890",
            "trackingUrl": "https://www.dhl.com/track/1234567890"
          },
          "lastMile": {
            "carrier": "USPS",
            "trackingNumber": "9400100000000000000000",
            "trackingUrl": "https://tools.usps.com/go/TrackConfirmAction?tLabels=9400100000000000000000"
          }
        }

        ```


        ## Important Details


        ### Events Array


        The `events` field is an **array** containing the complete event history
        for the shipment, not just the most recent event. Each event includes:

        - **timestamp**: When the event occurred (UTC timezone)

        - **code**: Event code from the carrier

        - **description**: Human-readable event description

        - **location**: Where the event occurred (if available)


        ### ObjectId and ObjectType


        - **objectId**: The unique identifier of the shipment, manifest, or
        other object this event relates to

        - **objectType**: The type of object ("shipment", "manifest", etc.)


        These fields help you identify which specific object the event relates
        to in your system.


        ### Timezone


        All timestamps in webhook payloads are in **UTC timezone** (ISO 8601
        format). Convert to your local timezone as needed.


        ### FirstMile and LastMile


        The `firstMile` and `lastMile` objects contain external carrier tracking
        information:


        - **firstMile**: Information about the pickup/departure carrier

        - **lastMile**: Information about the final delivery carrier


        These fields are only populated when:

        - The shipment uses multiple carriers (e.g., international shipments)

        - External tracking numbers are available

        - The carriers provide tracking URLs


        The events in the `events` array come from both first-mile and last-mile
        carriers, providing a complete picture of the shipment's journey.


        ## Best Practices


        1. **Verify signatures** - Always verify the webhook signature to ensure
        authenticity

        2. **Handle duplicates** - Webhooks may be sent multiple times; use
        event IDs to prevent duplicate processing

        3. **Respond quickly** - Return a 2xx status code immediately, then
        process the event asynchronously

        4. **Handle failures gracefully** - Implement retry logic for failed
        webhook processing

        5. **Monitor webhook health** - Track webhook delivery success rates and
        response times


        ## Example Implementation


        ```javascript

        // Express.js webhook handler example

        app.post('/webhooks/teleship', express.raw({type: 'application/json'}),
        (req, res) => {
          const signature = req.headers['x-teleship-signature'];
          const payload = req.body;

          // Verify signature
          if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
            return res.status(400).send('Invalid signature');
          }

          // Parse payload
          const event = JSON.parse(payload);

          // Handle different event types
          switch (event.eventName) {
            case 'label.generated':
              handleLabelGenerated(event.data);
              break;
            case 'shipment.updated':
              handleShipmentUpdated(event.data);
              break;
            default:
              console.log('Unhandled event type:', event.eventName);
          }

          // Respond quickly
          res.status(200).send('OK');
        });

        ```


        ## Why use webhooks?


        - **Real-time updates**: Get instant notifications when shipment status
        changes

        - **Automation**: Trigger workflows based on shipping events

        - **Integration**: Sync shipment data with your order management system

        - **Customer experience**: Update customers with real-time tracking
        information
            
      operationId: registerWebhook
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWebhookDto'
            examples:
              ShipmentUpdates:
                value:
                  url: https://example.com/webhook
                  description: Shopify app tracking milestones Webhook
                  enabledEvents:
                    - shipment.updated
              AllEvents:
                value:
                  url: https://example.com/webhook
                  enabledEvents:
                    - '*'
              CustomsDocumentUpdates:
                value:
                  url: https://example.com/webhook
                  enabledEvents:
                    - document.uploaded
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookDto'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResponseMessagesDto'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResponseMessagesDto'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResponseMessagesDto'
      security:
        - bearer: []
components:
  schemas:
    CreateWebhookDto:
      type: object
      properties:
        url:
          type: string
          description: The URL of the webhook endpoint.
        description:
          type: string
          description: An optional description of what the webhook is used for.
        enabled:
          type: boolean
        enabledEvents:
          type: array
          description: >-
            The list of events to enable for this endpoint. ['*'] indicates that
            all events are enabled, except those that require explicit
            selection.
          items:
            type: string
            enum:
              - '*'
              - label.generated
              - shipment.updated
              - manifest.created
              - document.uploaded
              - taxes.collection.ready
              - taxes.collection.updated
              - taxes.collection.cancelled
              - taxes.collection.exception
              - product.classification.complete
              - product.updated
        metadata:
          type: object
          description: >-
            Set of key-value pairs that you can attach to an object. This can be
            useful for storing additional information about the object in a
            structured format.
      required:
        - url
        - enabled
        - enabledEvents
    WebhookDto:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the object.
        url:
          type: string
          description: The URL of the webhook endpoint.
        description:
          type: string
          description: An optional description of what the webhook is used for.
        enabledEvents:
          type: array
          description: The list of events to enable for this endpoint.
          items:
            type: string
            enum:
              - '*'
              - label.generated
              - shipment.updated
              - manifest.created
              - document.uploaded
              - taxes.collection.ready
              - taxes.collection.updated
              - taxes.collection.cancelled
              - taxes.collection.exception
              - product.classification.complete
              - product.updated
        secret:
          type: string
          description: >-
            The endpoint’s secret, used to generate webhook signatures. Only
            returned at creation.
        enabled:
          type: boolean
          description: The status of the webhook. It can be enabled or disabled.
        metadata:
          type: object
          description: >-
            Set of key-value pairs that you can attach to an object. This can be
            useful for storing additional information about the object in a
            structured format.
      required:
        - id
        - url
        - enabledEvents
        - secret
        - enabled
    ResponseMessagesDto:
      type: object
      properties:
        messages:
          type: array
          items:
            $ref: '#/components/schemas/ErrorResponseDto'
      required:
        - messages
    ErrorResponseDto:
      type: object
      properties:
        code:
          type: number
        level:
          type: string
          enum:
            - error
            - warning
            - info
          example: error
          description: Error level
          default: error
        timestamp:
          format: date-time
          type: string
          example: '2024-01-01T00:00:00.00Z'
        message:
          type: string
          example: An error occurred
        details:
          example:
            - Missing required field
          type: array
          items:
            type: string
      required:
        - code
        - level
        - timestamp
        - message
        - details
  securitySchemes:
    bearer:
      scheme: bearer
      bearerFormat: JWT
      type: http

````