Skip to content

Buy a bundle

POST
/purchases
curl --request POST \
--url https://api.poweredbyaura.com/v1/purchases \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "reference": "order-10293", "phone_number": "+2348000000001", "bundle_id": "bnd_ng_a_1gb_1d", "metadata": { "customer_id": "cus_88412" } }'

Buys a bundle for a phone number. The response is the purchase in its current state, which is usually pending. Follow it to a final state with a webhook or by looking it up.

reference is your own unique ID for the purchase and makes the request safe to retry. Sending the same reference with the same body returns the original purchase with status 200 and the header Aura-Idempotent-Replay: true, and never buys twice. Sending it with a different body returns 409 reference_conflict.

Media typeapplication/json
object
reference
required

Your unique ID for this purchase. Letters, numbers, -, _, . and :, up to 64 characters.

string
/^[A-Za-z0-9._:-]{1,64}$/
phone_number
required

The number to credit, in E.164 format.

string
bundle_id
required
string
network_id

Optional. If you send it, Aura checks the number is on this network and refuses the purchase with network_mismatch if not. If you leave it out, Aura uses the bundle’s network after looking the number up.

string
metadata

Up to 20 keys of your own, returned on the purchase and in webhooks. Values are strings of up to 500 characters.

object
<= 20 properties
key
additional properties
string
<= 500 characters

Examples

Examplepurchase

Buy 1GB for a customer

{
"reference": "order-10293",
"phone_number": "+2348000000001",
"bundle_id": "bnd_ng_a_1gb_1d",
"metadata": {
"customer_id": "cus_88412"
}
}

A purchase with this reference and the same body already exists. It is returned unchanged.

Media typeapplication/json
object
id
required
string
object
required
string
Allowed value: purchase
reference
required
string
status
required

pending: accepted, waiting for the network’s confirmation. successful: the network confirmed the bundle was credited, and you were charged. failed: the bundle was not credited, and you were not charged. reversed: the network reversed a successful bundle, and you were refunded. successful, failed and reversed are final, except that successful can become reversed.

string
Allowed values: pending successful failed reversed
phone_number
required
string
network_id
required
string
bundle
required

The bundle as it was when bought.

object
id
required
string
name
required
string
data_mb
required
integer
validity_hours
required
integer
price
required

The amount held while pending, charged if successful, and refunded if reversed.

object
amount
required

Amount in the currency’s minor unit (kobo for NGN).

integer
currency
required

ISO 4217 currency code.

string
/^[A-Z]{3}$/
created_at
required
string format: date-time
resolve_by
required

The latest time by which this purchase will reach a final state. If the network has not confirmed by then, the purchase fails with network_timeout and nothing is charged.

string format: date-time
completed_at
required

When the purchase reached successful or failed.

string | null format: date-time
delivery
required

Present once the network has confirmed the bundle was credited.

object
confirmed_at
required
string format: date-time
network_reference
required

The network’s own reference for the credit, when the network provides one.

string | null
failure
required

Present when the purchase failed.

object
code
required

Why a purchase failed. New codes may be added in v1.

string
Allowed values: network_rejected number_not_eligible bundle_unavailable network_timeout internal_error
message
required
string
reversal
required

Present when a successful purchase was reversed.

object
reversed_at
required
string format: date-time
reason
required
string
metadata
required
object
key
additional properties
string

Examples

Examplesuccessful

Confirmed by the network

{
"id": "pur_01JA7ZK3Q9W2D8M5X4N6B1C0VE",
"object": "purchase",
"reference": "order-10293",
"status": "successful",
"phone_number": "+2348000000001",
"network_id": "net_ng_a",
"bundle": {
"id": "bnd_ng_a_1gb_1d",
"name": "1GB Daily",
"data_mb": 1024,
"validity_hours": 24
},
"price": {
"amount": 35000,
"currency": "NGN"
},
"created_at": "2026-10-12T09:14:30Z",
"resolve_by": "2026-10-12T09:44:30Z",
"completed_at": "2026-10-12T09:14:31Z",
"delivery": {
"confirmed_at": "2026-10-12T09:14:31Z",
"network_reference": "A-8841207731"
},
"failure": null,
"reversal": null,
"metadata": {
"customer_id": "cus_88412"
}
}
Aura-Request-Id
string
Example
req_7Kp2Vx9QmR4t

A unique ID for this request. Quote it when you contact your technical contact.

Aura-Idempotent-Replay
string
Allowed value: true

Always true on a replayed response.

The purchase was accepted. Its status is usually pending.

Media typeapplication/json
object
id
required
string
object
required
string
Allowed value: purchase
reference
required
string
status
required

pending: accepted, waiting for the network’s confirmation. successful: the network confirmed the bundle was credited, and you were charged. failed: the bundle was not credited, and you were not charged. reversed: the network reversed a successful bundle, and you were refunded. successful, failed and reversed are final, except that successful can become reversed.

string
Allowed values: pending successful failed reversed
phone_number
required
string
network_id
required
string
bundle
required

The bundle as it was when bought.

object
id
required
string
name
required
string
data_mb
required
integer
validity_hours
required
integer
price
required

The amount held while pending, charged if successful, and refunded if reversed.

object
amount
required

Amount in the currency’s minor unit (kobo for NGN).

integer
currency
required

ISO 4217 currency code.

string
/^[A-Z]{3}$/
created_at
required
string format: date-time
resolve_by
required

The latest time by which this purchase will reach a final state. If the network has not confirmed by then, the purchase fails with network_timeout and nothing is charged.

string format: date-time
completed_at
required

When the purchase reached successful or failed.

string | null format: date-time
delivery
required

Present once the network has confirmed the bundle was credited.

object
confirmed_at
required
string format: date-time
network_reference
required

The network’s own reference for the credit, when the network provides one.

string | null
failure
required

Present when the purchase failed.

object
code
required

Why a purchase failed. New codes may be added in v1.

string
Allowed values: network_rejected number_not_eligible bundle_unavailable network_timeout internal_error
message
required
string
reversal
required

Present when a successful purchase was reversed.

object
reversed_at
required
string format: date-time
reason
required
string
metadata
required
object
key
additional properties
string

Examples

Examplepending

Accepted, waiting for the network

{
"id": "pur_01JA7ZK3Q9W2D8M5X4N6B1C0VE",
"object": "purchase",
"reference": "order-10293",
"status": "pending",
"phone_number": "+2348000000001",
"network_id": "net_ng_a",
"bundle": {
"id": "bnd_ng_a_1gb_1d",
"name": "1GB Daily",
"data_mb": 1024,
"validity_hours": 24
},
"price": {
"amount": 35000,
"currency": "NGN"
},
"created_at": "2026-10-12T09:14:30Z",
"resolve_by": "2026-10-12T09:44:30Z",
"completed_at": null,
"delivery": null,
"failure": null,
"reversal": null,
"metadata": {
"customer_id": "cus_88412"
}
}
Aura-Request-Id
string
Example
req_7Kp2Vx9QmR4t

A unique ID for this request. Quote it when you contact your technical contact.

The request is malformed or a field is invalid. Fix it before retrying.

Media typeapplication/json
object
error
required
object
code
required

A stable, machine-readable code. New codes may be added in v1, so treat an unknown code by its HTTP status and retryable flag.

string
Allowed values: invalid_request invalid_phone_number invalid_api_key ip_not_allowed not_found insufficient_balance reference_conflict bundle_unavailable network_mismatch unsupported_network rate_limited internal_error network_unavailable
message
required

A human-readable explanation. Do not parse it; use code.

string
param

The request field the error is about, when there is one.

string
retryable
required

Whether the same request can succeed if you retry it later.

boolean
request_id
required
string
details

Extra facts about the error, such as the existing purchase or the network’s status.

object
key
additional properties
any

Examples

ExampleinvalidPhoneNumber
{
"error": {
"code": "invalid_phone_number",
"message": "phone_number must be in E.164 format, such as +2348000000001.",
"param": "phone_number",
"retryable": false,
"request_id": "req_9Qd4Hs1XvB7n"
}
}
Aura-Request-Id
string
Example
req_7Kp2Vx9QmR4t

A unique ID for this request. Quote it when you contact your technical contact.

The API key is missing, wrong or revoked.

Media typeapplication/json
object
error
required
object
code
required

A stable, machine-readable code. New codes may be added in v1, so treat an unknown code by its HTTP status and retryable flag.

string
Allowed values: invalid_request invalid_phone_number invalid_api_key ip_not_allowed not_found insufficient_balance reference_conflict bundle_unavailable network_mismatch unsupported_network rate_limited internal_error network_unavailable
message
required

A human-readable explanation. Do not parse it; use code.

string
param

The request field the error is about, when there is one.

string
retryable
required

Whether the same request can succeed if you retry it later.

boolean
request_id
required
string
details

Extra facts about the error, such as the existing purchase or the network’s status.

object
key
additional properties
any

Examples

ExampleinvalidKey
{
"error": {
"code": "invalid_api_key",
"message": "The API key is not valid.",
"retryable": false,
"request_id": "req_2Mz6Rt8KcW1p"
}
}
Aura-Request-Id
string
Example
req_7Kp2Vx9QmR4t

A unique ID for this request. Quote it when you contact your technical contact.

Your balance does not cover this purchase. Nothing was bought.

Media typeapplication/json
object
error
required
object
code
required

A stable, machine-readable code. New codes may be added in v1, so treat an unknown code by its HTTP status and retryable flag.

string
Allowed values: invalid_request invalid_phone_number invalid_api_key ip_not_allowed not_found insufficient_balance reference_conflict bundle_unavailable network_mismatch unsupported_network rate_limited internal_error network_unavailable
message
required

A human-readable explanation. Do not parse it; use code.

string
param

The request field the error is about, when there is one.

string
retryable
required

Whether the same request can succeed if you retry it later.

boolean
request_id
required
string
details

Extra facts about the error, such as the existing purchase or the network’s status.

object
key
additional properties
any

Examples

ExampleinsufficientBalance
{
"error": {
"code": "insufficient_balance",
"message": "Your available balance is lower than the price of this bundle.",
"retryable": false,
"request_id": "req_7Kp2Vx9QmR4t"
}
}
Aura-Request-Id
string
Example
req_7Kp2Vx9QmR4t

A unique ID for this request. Quote it when you contact your technical contact.

The key is valid but this request is not allowed, for example from an IP address outside your allowlist.

Media typeapplication/json
object
error
required
object
code
required

A stable, machine-readable code. New codes may be added in v1, so treat an unknown code by its HTTP status and retryable flag.

string
Allowed values: invalid_request invalid_phone_number invalid_api_key ip_not_allowed not_found insufficient_balance reference_conflict bundle_unavailable network_mismatch unsupported_network rate_limited internal_error network_unavailable
message
required

A human-readable explanation. Do not parse it; use code.

string
param

The request field the error is about, when there is one.

string
retryable
required

Whether the same request can succeed if you retry it later.

boolean
request_id
required
string
details

Extra facts about the error, such as the existing purchase or the network’s status.

object
key
additional properties
any

Examples

ExampleipNotAllowed
{
"error": {
"code": "ip_not_allowed",
"message": "Requests from 203.0.113.24 are not on your account's allowlist.",
"retryable": false,
"request_id": "req_5Tg1Nq7JpL3x"
}
}
Aura-Request-Id
string
Example
req_7Kp2Vx9QmR4t

A unique ID for this request. Quote it when you contact your technical contact.

A purchase with this reference exists with a different body. Nothing was bought.

Media typeapplication/json
object
error
required
object
code
required

A stable, machine-readable code. New codes may be added in v1, so treat an unknown code by its HTTP status and retryable flag.

string
Allowed values: invalid_request invalid_phone_number invalid_api_key ip_not_allowed not_found insufficient_balance reference_conflict bundle_unavailable network_mismatch unsupported_network rate_limited internal_error network_unavailable
message
required

A human-readable explanation. Do not parse it; use code.

string
param

The request field the error is about, when there is one.

string
retryable
required

Whether the same request can succeed if you retry it later.

boolean
request_id
required
string
details

Extra facts about the error, such as the existing purchase or the network’s status.

object
key
additional properties
any

Examples

ExamplereferenceConflict
{
"error": {
"code": "reference_conflict",
"message": "A purchase with reference 'order-10293' already exists with a different phone_number.",
"retryable": false,
"request_id": "req_3Fh8Lw2NcY6d",
"details": {
"purchase_id": "pur_01JA7ZK3Q9W2D8M5X4N6B1C0VE"
}
}
}
Aura-Request-Id
string
Example
req_7Kp2Vx9QmR4t

A unique ID for this request. Quote it when you contact your technical contact.

The request is well formed but cannot be carried out. Nothing was bought.

Media typeapplication/json
object
error
required
object
code
required

A stable, machine-readable code. New codes may be added in v1, so treat an unknown code by its HTTP status and retryable flag.

string
Allowed values: invalid_request invalid_phone_number invalid_api_key ip_not_allowed not_found insufficient_balance reference_conflict bundle_unavailable network_mismatch unsupported_network rate_limited internal_error network_unavailable
message
required

A human-readable explanation. Do not parse it; use code.

string
param

The request field the error is about, when there is one.

string
retryable
required

Whether the same request can succeed if you retry it later.

boolean
request_id
required
string
details

Extra facts about the error, such as the existing purchase or the network’s status.

object
key
additional properties
any

Examples

{
"error": {
"code": "bundle_unavailable",
"message": "Bundle bnd_ng_a_10gb_30d cannot be bought right now.",
"param": "bundle_id",
"retryable": false,
"request_id": "req_4Np9Kx2ZsD6v"
}
}
Aura-Request-Id
string
Example
req_7Kp2Vx9QmR4t

A unique ID for this request. Quote it when you contact your technical contact.

Too many requests. Wait for Retry-After seconds, then retry.

Media typeapplication/json
object
error
required
object
code
required

A stable, machine-readable code. New codes may be added in v1, so treat an unknown code by its HTTP status and retryable flag.

string
Allowed values: invalid_request invalid_phone_number invalid_api_key ip_not_allowed not_found insufficient_balance reference_conflict bundle_unavailable network_mismatch unsupported_network rate_limited internal_error network_unavailable
message
required

A human-readable explanation. Do not parse it; use code.

string
param

The request field the error is about, when there is one.

string
retryable
required

Whether the same request can succeed if you retry it later.

boolean
request_id
required
string
details

Extra facts about the error, such as the existing purchase or the network’s status.

object
key
additional properties
any

Examples

ExamplerateLimited
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Retry after 2 seconds.",
"retryable": true,
"request_id": "req_6Yf2Pk8GwN4s"
}
}
Aura-Request-Id
string
Example
req_7Kp2Vx9QmR4t

A unique ID for this request. Quote it when you contact your technical contact.

Retry-After
integer

Seconds to wait before retrying.

RateLimit-Limit
integer

Requests allowed in the current window.

RateLimit-Remaining
integer

Requests left in the current window.

RateLimit-Reset
integer

Seconds until the current window resets.

Something went wrong on Aura’s side. Retry with the same reference; it will never buy twice.

Media typeapplication/json
object
error
required
object
code
required

A stable, machine-readable code. New codes may be added in v1, so treat an unknown code by its HTTP status and retryable flag.

string
Allowed values: invalid_request invalid_phone_number invalid_api_key ip_not_allowed not_found insufficient_balance reference_conflict bundle_unavailable network_mismatch unsupported_network rate_limited internal_error network_unavailable
message
required

A human-readable explanation. Do not parse it; use code.

string
param

The request field the error is about, when there is one.

string
retryable
required

Whether the same request can succeed if you retry it later.

boolean
request_id
required
string
details

Extra facts about the error, such as the existing purchase or the network’s status.

object
key
additional properties
any

Examples

ExampleinternalError
{
"error": {
"code": "internal_error",
"message": "Something went wrong on our side. Retry with the same reference.",
"retryable": true,
"request_id": "req_3Js8Bd1RxK7m"
}
}
Aura-Request-Id
string
Example
req_7Kp2Vx9QmR4t

A unique ID for this request. Quote it when you contact your technical contact.

The network cannot take purchases right now. The error carries its live status. Nothing was bought.

Media typeapplication/json
object
error
required
object
code
required

A stable, machine-readable code. New codes may be added in v1, so treat an unknown code by its HTTP status and retryable flag.

string
Allowed values: invalid_request invalid_phone_number invalid_api_key ip_not_allowed not_found insufficient_balance reference_conflict bundle_unavailable network_mismatch unsupported_network rate_limited internal_error network_unavailable
message
required

A human-readable explanation. Do not parse it; use code.

string
param

The request field the error is about, when there is one.

string
retryable
required

Whether the same request can succeed if you retry it later.

boolean
request_id
required
string
details

Extra facts about the error, such as the existing purchase or the network’s status.

object
key
additional properties
any

Examples

ExamplenetworkUnavailable
{
"error": {
"code": "network_unavailable",
"message": "net_ng_a is not accepting purchases right now.",
"retryable": true,
"request_id": "req_7Cv5Gm2TzP8h",
"details": {
"network": {
"id": "net_ng_a",
"status": "unavailable",
"status_message": "The network is not confirming purchases. We are working with it.",
"status_updated_at": "2026-10-12T09:02:00Z"
}
}
}
}
Aura-Request-Id
string
Example
req_7Kp2Vx9QmR4t

A unique ID for this request. Quote it when you contact your technical contact.

Retry-After
integer

Seconds to wait before retrying.