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

# Create an order

> Create a new eSIM order

## Authentication

This endpoint requires HMAC-SHA256 signature authentication. See [Authentication guide](/authentication/overview#api-partner-authentication) for details.

## Headers

<ParamField header="X-Esim-Story-Access-Key" type="string" required>
  Your partner access key. Used for authentication.
</ParamField>

<ParamField header="X-Esim-Story-Signature" type="string" required>
  HMAC-SHA256 signature of the request. Generated using your secret key. See
  [Authentication guide](/authentication/overview#api-partner-authentication)
  for signature generation details.
</ParamField>

<ParamField header="X-Esim-Story-Timestamp" type="string" required>
  Unix timestamp in seconds (UTC). Must be within the allowed time window of the current time.
</ParamField>

## Request Body

<ParamField body="external_order_id" type="string" required>
  Your order identifier in your system. Must be unique.
</ParamField>

<ParamField body="products" type="array" required>
  Array of products to order. Each product must include: - `option_id` (string,
  required): The eSIM product option ID - `qty` (integer, required): Quantity of
  this product to order
</ParamField>

<RequestExample>
  ```bash Endpoint theme={null}
  POST /v1/api_partner/orders
  ```

  ```json Body theme={null}
  {
    "external_order_id": "ORDER-123456",
    "products": [
      {
        "option_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "qty": 1
      },
      {
        "option_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
        "qty": 2
      }
    ]
  }
  ```
</RequestExample>

## Response

<ResponseField name="products" type="array">
  Array of products with their assigned topup IDs. Each product includes: -
  `topup_id` (string): The topup ID assigned to this product - `option_id`
  (string): The option ID that was ordered
</ResponseField>

<ResponseExample>
  ```json Response theme={null}
  {
    "products": [
      {
        "topup_id": "20250129123456123456789012",
        "option_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
      },
      {
        "topup_id": "20250129123456123456789013",
        "option_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
      },
      {
        "topup_id": "20250129123456123456789014",
        "option_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
      }
    ]
  }
  ```
</ResponseExample>

### Error Responses

#### 400 Bad Request

Invalid request payload or JSON parsing error:

```json theme={null}
{
  "error": "Invalid JSON format"
}
```

Common causes:

* Malformed JSON in request body
* Invalid JSON syntax
* Missing or empty request body

#### 401 Unauthorized

Authentication failed:

```json theme={null}
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid signature."
  }
}
```

Common authentication errors:

* **Missing required authentication headers**: One or more of `X-Esim-Story-Access-Key`, `X-Esim-Story-Signature`, or `X-Esim-Story-Timestamp` headers are missing

  ```json theme={null}
  {
    "error": {
      "code": "unauthorized",
      "message": "Missing required authentication headers."
    }
  }
  ```

* **Invalid access key**: The provided access key does not exist in the system

  ```json theme={null}
  {
    "error": {
      "code": "unauthorized",
      "message": "Invalid or missing access key. Please provide a valid X-Esim-Story-Access-Key header."
    }
  }
  ```

* **Invalid signature**: The HMAC signature does not match the expected signature

  ```json theme={null}
  {
    "error": {
      "code": "unauthorized",
      "message": "Invalid signature."
    }
  }
  ```

* **Request timestamp is too old or invalid**: The timestamp must be within the allowed time window of the current time

  ```json theme={null}
  {
    "error": {
      "code": "unauthorized",
      "message": "Request timestamp is too old or invalid."
    }
  }
  ```

* **Missing secret key**: The partner record is missing a secret key
  ```json theme={null}
  {
    "error": {
      "code": "unauthorized",
      "message": "Missing secret key in partner record."
    }
  }
  ```

#### 422 Unprocessable Entity

Validation errors or business logic errors:

**Product not found**:
When an `option_id` in the products array does not exist in the system:

```json theme={null}
{
  "errors": ["Product with option_id not found"]
}
```

**Missing required fields**:

```json theme={null}
{
  "errors": ["External order id can't be blank"]
}
```

**Duplicate external\_order\_id**:

```json theme={null}
{
  "errors": ["External order id has already been taken"]
}
```

**Invalid products array**:

* Empty products array
* Missing `option_id` or `qty` in product objects
* Invalid `qty` value (must be a positive integer)

**eSIM API errors**:
When the external eSIM provider API returns an error:

```json theme={null}
{
  "errors": ["eSIM Request failed - Status: [code], Message: [message]"]
}
```

**API connection errors**:
When there's a network error connecting to the eSIM provider:

```json theme={null}
{
  "errors": ["API connection error (Order ID: [order_id])"]
}
```

#### 500 Internal Server Error

Server error during order processing:

```json theme={null}
{
  "error": "Internal server error"
}
```

Common causes:

* Database connection errors
* Unexpected server errors
* External service failures

## Notes

* The `external_order_id` must be unique.
* Each product in the `products` array will be ordered `qty` times.
* The response includes one `topup_id` per quantity ordered (e.g., if `qty: 2`, you'll receive 2 entries with different `topup_id` values).
* Orders are processed asynchronously. The response indicates successful order creation, but eSIM activation may take additional time.
* **You must configure a webhook URL to receive eSIM data**. If no webhook URL is configured, you will not receive eSIM activation data.
* In sandbox environment, orders use test data and do not result in actual eSIM purchases.

## Example: Ordering Multiple Quantities

If you order a product with `qty: 2`, you'll receive 2 separate entries in the response:

```json theme={null}
{
  "products": [
    {
      "topup_id": "20250129123456123456789012",
      "option_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    },
    {
      "topup_id": "20250129123456123456789013",
      "option_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    }
  ]
}
```

## Webhooks

After successfully creating an order, eSIM data will be delivered to your configured webhook URL once the eSIM is ready. A webhook URL must be configured in your partner account to receive callbacks.

**Webhooks are sent via POST requests** to your configured webhook URL. Your webhook endpoint should return a `200 OK` status code to acknowledge successful receipt.

**One webhook is sent per order item**. For example, if you order a product with `qty: 2`, you will receive 2 separate webhook requests (one for each quantity ordered).

### Example Response

```json theme={null}
{
  "topup_id": "20250129123456123456789012",
  "option_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "iccid": "89852341234567890123",
  "smdp": "rsp1.cmlink.com",
  "activate_code": "A1B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6",
  "download_link": "LPA:1$rsp1.cmlink.com$A1B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6",
  "qrcode_img_url": "https://func-usimsa-prod-01.azurewebsites.net/api/iccid/qrcode/LPA:1%24rsp1.cmlink.com%24A1B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6/120",
  "expired_date": "2026-07-28",
  "external_order_id": "ORDER-123456"
}
```
