> ## 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

> Add manual tracking events to a Shipment — for warehouse milestones, quality checks, refunds, and anything carriers don't report.

Carrier events flow into Perform.AI automatically. `POST /v5/events/create/` adds **manual events** on top — steps carriers can't see: warehouse handling, quality checks on returns, refund progress. Manual events appear everywhere carrier events do: tracking pages, notifications, webhooks, and the Parcel Details timeline. Full specs: [API reference](/api-reference/v5/events/create-events).

## Prerequisites

The Shipment must already have a **`tracking_number` and an assigned carrier** — otherwise the request is rejected with `Manual events cannot be created for shipment as a tracking_number and carrier has not been assigned.` (For Return Shipments, the Return Booking Service assigns both when the label is generated.)

## The request

Identify the Shipment by `shipment_uuid` **or** `shipment_id` in the body; `events` is a required array:

```bash theme={null}
curl --request POST \
  --url https://api.perform.ai/v5/events/create/ \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "shipment_id": "SHP-2026-000002",
    "events": [
      {
        "description": "Package received at warehouse",
        "date_time": "2026-09-20T10:30:55+08:00",
        "location": { "place": "Singapore" },
        "additional_info": { "dock": "D4" }
      }
    ]
  }'
```

Each event carries **either** a free-text `description` (max 250 chars) **or** a `standard_key` — a Perform.AI standard event key (e.g. `H11`) that maps the event to the standard taxonomy and phases. The key list is available from your account team.

Rules that matter:

* **If both `description` and `standard_key` are sent, `standard_key` wins** and the description is ignored — the response is a 299 warning, not an error.
* `date_time` defaults to now (UTC) when omitted; send an explicit offset or `Z` for local times.
* If you send a `location`, its `place` is required.
* **Events are added, never replaced** — there is no way to edit or delete an event via the API, so validate before sending.
* A Pending outbound Shipment becomes Active, Delivered, or Undeliverable when its first event lands, depending on the event.

<Tip>
  For Return Shipments, use `description` values your customers understand — for example: *Quality check in progress*, *Quality check processed - items accepted*, *Refund being processed*, *Refund successfully processed*.
</Tip>

## The response

Success carries no data payload:

```json theme={null}
{ "api_response": "200" }
```

A `299` means the events were created but something was adjusted (see `warnings`); a `4030` means nothing was created — most commonly the missing tracking-number/carrier precondition, a missing `description`/`standard_key`, or an unrecognized standard key.
