---
title: "Remove a data package"
method: DELETE
path: "/v1/esim/sims/{esim_id}/packages/{package_id}"
tags: ["esims"]
---

# Remove a data package

`DELETE /v1/esim/sims/{esim_id}/packages/{package_id}`

## Request

- Base URL: `https://us1.platform.bird.com`
- URL: `https://us1.platform.bird.com/v1/esim/sims/{esim_id}/packages/{package_id}`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `bird_session`

Removes a data package and frees capacity under the eSIM's `package_limit`. Remaining data is forfeited without a refund. If usable balance remains, the request returns `409` unless `acknowledge_balance_forfeit=true`.

A `202` response returns the package in `removing`. Use [Get a data package](/docs/api/reference/get-esim-package) to confirm `removed`. If the network rejects removal, the package returns to its previous status.

## Query parameters

- `acknowledge_balance_forfeit` boolean

## Headers

- `Idempotency-Key` string
- `X-Workspace-Id` string
- `X-Organization-Id` string

## Response `202`

Removal in progress. The returned package is in `removing`; it reaches `removed` once complete, confirmed by the esim.package.removed event.

- EsimPackage: One data package held by an eSIM: a single purchase with its own balance, validity, and coverage zone. Every order that completes creates exactly one package, so a package is always traceable to the order that bought it. An eSIM can hold several packages per zone; the right one is consumed automatically based on the device's location, and zone_balances on the eSIM carries the combined remainder per zone.
  - `id` string, required
  - `order_id` string, required
  - `offer_id` string, required
  - `zone_id` string, required
  - `zone_name` string, required: Coverage zone name, from the offer.
  - `countries` CountryCode[], required: Countries the package's zone covers, captured at purchase time so the package is meaningful without fetching the offer.
  - `status` 'provisioning' | 'pending_first_use' | 'active' | 'depleted' | 'expired' | 'removing' | 'removed' | 'failed', required: Lifecycle state of a data package. - `provisioning`: being applied to the eSIM. - `pending_first_use`: confirmed; activates on first use in its coverage zone. - `active`: consuming data; validity is running. - `depleted`: balance fully used. - `expired`: validity ended; unused balance is gone. - `removing`: a removal was requested and is being applied. On definitive rejection the package returns to its prior status, reported by `esim.operation_failed`. - `removed`: taken off the eSIM at your request; remaining balance forfeited. - `failed`: could not be applied; any charge is credited back automatically through the owning order, which reports this through its `failed` status and the `esim.order.failed` event.
  - `speed` 'full' | 'reduced', required: Speed class. full: data flows at full network speed until the allowance is used; reduced: speed is limited, typically after the full-speed allowance. Full-speed and reduced-speed packages cannot be combined on one eSIM.
  - `balance` EsimPackageBalance, required: Package allowance and reported consumption. `total_bytes` is the purchased allowance. `used_bytes`, `remaining_bytes`, and `used_percent` are null until usage is reported. Reports can lag device usage; use `as_of` to show when the balance was updated.
    - `total_bytes` integer, required: Total data in bytes, as purchased. Known from the order, so never null.
    - `used_bytes` integer, nullable, required: Data used in bytes, or null while no network has reported on this package.
    - `remaining_bytes` integer, nullable, required: Data remaining in bytes, or null while no network has reported on this package.
    - `used_percent` number, nullable, required: Share of the total data already used, as a percentage. Null while no network has reported on this package.
    - `as_of` string, date-time, required: When the balance was last established. Before consumption is reported, this is the package delivery time. Check whether the consumption fields are null before treating this timestamp as a usage update.
    - `observed_at` string, date-time, nullable, required: Measurement time supplied by the mobile network. Null when no measurement or measurement time is available. Use `as_of` for the balance update time.
  - `activated_at` string, date-time, nullable: When the package started consuming data (first use in its zone). Null until then.
  - `expires_at` string, date-time, nullable: When the package's validity ends and unused balance expires. Already capped by the eSIM's service period, so this is always the effective expiry. Null until the package activates.
  - `price` Money, required
    - `amount` string, required: Decimal amount as a string, in major currency units.
    - `currency_code` string, required: ISO 4217 three-letter currency code.
  - `created_at` string, date-time, required

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `403`: Insufficient permissions
- `404`: Resource not found
- `409`: Resource conflict
- `422`: The request has invalid field values, violates a business rule, or carries a query parameter the endpoint does not declare. Field validation errors use `type: validation_error` and include the affected fields in `details`. Business-rule errors identify the failed rule in `type`.
- `429`: Rate limit exceeded
- `500`: Internal server error
- `503`: The service is temporarily unavailable. If `Retry-After` is present, wait for that delay before retrying; otherwise, retry with exponential backoff. Reuse the same idempotency key and request when retrying a mutation.

---

[API](https://skmtc.dev/messagebird/apis/bird-api.md) · [All operations](https://skmtc.dev/messagebird/apis/bird-api/llms.txt) · [OpenAPI document](https://skmtc.dev/messagebird/apis/bird-api/revisions/3e2a50466454?raw)
