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

# Create Events

> Adds manual tracking events to an existing Shipment — outbound or
return. Identify the Shipment with `shipment_uuid` **or** `shipment_id`
in the body; the `events` array is required.

**Preconditions:** the Shipment must already have a `tracking_number`
and an assigned carrier — otherwise the request is rejected. Each event
needs a `description` **or** a `standard_key` (the standard event key
list is available from your account team); if both are sent,
`standard_key` wins and `description` is ignored with a 299 warning.

Events are **added**, never replaced. A Pending outbound Shipment
becomes Active, Delivered, or Undeliverable when its first event
arrives, depending on the event.



## OpenAPI

````yaml /specs/public-api-v5.yaml post /v5/events/create/
openapi: 3.1.0
info:
  title: Perform.AI Public API (v5)
  version: 5.0.0
  description: |-
    The Perform.AI Public API lets you create and manage shipments, returns,
    bookings, tracking events, and documents, and retrieve reference data such
    as PUDO locations and carrier configurations.

    All endpoints accept HTTPS connections only and are secured with OAuth 2.0.
    Generate a Bearer access token with your API credentials (Client ID and
    Client Secret, from **Integrations > API** in your account), then send it in
    the `Authorization` header of every request.

    This specification covers the following endpoints:
    - `POST /auth/oauth/token/`
    - `POST /v5/shipment/`
    - `POST /v5/shipment/update/`
    - `POST /v5-2-0/shipment/update/`
    - `GET /v5/shipment/list/`
    - `GET /v5/shipment/details/`
    - `GET /v5-2-0/shipment/details/`
    - `POST /v5/events/create/`
    - `POST /v5/return/`
    - `POST /v5/return/update/`
    - `GET /v5/shipments/documents/`
    - `GET /v5/shipments/documents/{document_uuid}/`
    - `GET /v5/shipments/documents/labels/`
    - `POST /v5/booking/`
    - `GET /v5/pudo-locations/`
    - `GET /v5/carrier-configs/`
servers:
  - url: https://api.perform.ai
security:
  - BearerAuth: []
tags:
  - name: Authentication
    description: Generate the Bearer access token used by every other endpoint.
  - name: Shipments
    description: Create, update, search, and retrieve Shipments.
  - name: Events
    description: Add manual tracking events to Shipments.
  - name: Returns
    description: Create and update Returns and their Return Shipments.
  - name: Documents
    description: Retrieve documents attached to Shipments.
  - name: Booking
    description: Book Open Shipments with carriers and provision shipping labels.
  - name: PUDO locations
    description: Search pick-up/drop-off locations across your configured carriers.
  - name: Carrier configurations
    description: Discover the carriers configured in your account.
  - name: Webhooks
    description: Shipment update payloads Perform.AI pushes to your endpoint.
paths:
  /v5/events/create/:
    post:
      tags:
        - Events
      summary: Create Events
      description: |-
        Adds manual tracking events to an existing Shipment — outbound or
        return. Identify the Shipment with `shipment_uuid` **or** `shipment_id`
        in the body; the `events` array is required.

        **Preconditions:** the Shipment must already have a `tracking_number`
        and an assigned carrier — otherwise the request is rejected. Each event
        needs a `description` **or** a `standard_key` (the standard event key
        list is available from your account team); if both are sent,
        `standard_key` wins and `description` is ignored with a 299 warning.

        Events are **added**, never replaced. A Pending outbound Shipment
        becomes Active, Delivered, or Undeliverable when its first event
        arrives, depending on the event.
      operationId: post-v5-events-create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - events
              properties:
                shipment_uuid:
                  type: string
                  format: uuid
                  description: Provide this or `shipment_id`.
                shipment_id:
                  type: string
                  maxLength: 50
                  description: Provide this or `shipment_uuid`.
                events:
                  type: array
                  items:
                    $ref: '#/components/schemas/EventInput'
            example:
              shipment_id: SHP-2026-000002
              events:
                - description: Delivered Successfully
                  date_time: '2026-09-20T10:30:55+08:00'
                  location:
                    place: Singapore
      responses:
        '200':
          description: Events created. The response carries no data payload.
          content:
            application/json:
              schema:
                type: object
                properties:
                  api_response:
                    type: string
              example:
                api_response: '200'
        '299':
          description: >-
            Events created with warnings — e.g. `Description value ignored as
            both description and standard_key provided.`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessWithWarnings'
        '400':
          description: |-
            Validation failed. Causes: `Either shipment_uuid or shipment_id is
            required.`, `Either description or standard_key is required.`,
            `Please provide a valid standard event key.`, `Manual events cannot
            be created for shipment as a tracking_number and carrier has not
            been assigned.`, `Place is required.`, datetime format errors.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FieldValidationError'
              example:
                api_response: '4030'
                message: validation_error
                errors:
                  shipment: >-
                    Manual events cannot be created for shipment as a
                    tracking_number and carrier has not been assigned.
        '403':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/Throttled'
        '500':
          $ref: '#/components/responses/SystemError'
components:
  schemas:
    EventInput:
      type: object
      description: >-
        One manual event. Provide `description` **or** `standard_key`; if both,
        `standard_key` wins and `description` is ignored (299 warning). The
        Shipment must already have a tracking number and an assigned carrier.
      properties:
        description:
          type: string
          maxLength: 250
        standard_key:
          type: string
          maxLength: 5
          description: >-
            A Perform.AI standard event key. The key list is available from your
            account team.
        date_time:
          type: string
          description: ISO 8601. Defaults to the current time (UTC) when omitted.
        location:
          type: object
          properties:
            place:
              type: string
              maxLength: 250
              description: Required if `location` is provided.
        additional_info:
          type: object
          description: Custom fields. Keys max 50 chars, values max 150.
    SuccessWithWarnings:
      type: object
      description: >-
        HTTP 299 — the request succeeded, but parts of it could not be applied.
        The `warnings` object maps each affected field to its messages.
      required:
        - api_response
        - warnings
      properties:
        api_response:
          type: string
          description: Always `"299"`.
        data:
          type: object
          description: The endpoint's normal success payload, when it has one.
        warnings:
          type: object
          description: Affected field → array of warning messages.
          additionalProperties:
            type: array
            items:
              type: string
    FieldValidationError:
      type: object
      description: >-
        HTTP 400 — one or more fields failed validation; nothing was persisted.
        For fields inside arrays, errors are keyed by the item's position as a
        string ("0", "1", …), then the field name.
      required:
        - api_response
        - message
        - errors
      properties:
        api_response:
          type: string
          description: Always `"4030"`.
        message:
          type: string
          description: Always `validation_error`.
        errors:
          type: object
          description: >-
            Affected field → array of error messages (or a nested object for
            array items).
    GatewayError:
      type: object
      description: >-
        An error generated at the API gateway — authorization (`403`) or
        throttling (`429`). Note `api_response` is a number here, unlike
        application-level responses where it is a string.
      required:
        - api_response
        - message
      properties:
        api_response:
          type: integer
          description: '`403` or `429`.'
        message:
          type: string
          description: E.g. `Key not authorized`, `Quota exceeded`, `Throttled`.
    RequestError:
      type: object
      description: >-
        A request-level error such as `4000` (invalid request format), `4041`
        (no results found), or a `5XX` system error.
      required:
        - api_response
        - message
      properties:
        api_response:
          type: string
          description: Error code as a string, e.g. `"4000"`, `"4041"`, `"500"`.
        message:
          type: string
  responses:
    Unauthorized:
      description: >-
        The Bearer token is expired, invalid, or missing — or the account lacks
        access.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/GatewayError'
          example:
            api_response: 403
            message: Key not authorized
    Throttled:
      description: Rate limit exceeded (40 requests per second per account).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/GatewayError'
          example:
            api_response: 429
            message: Throttled
    SystemError:
      description: Internal system error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RequestError'
          example:
            api_response: '500'
            message: System error
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Used by every functional endpoint. Generate the token with `POST
        /auth/oauth/token/` and send it as `Authorization: Bearer {token}`.

````