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

# The Next action object

> What the customer must do to complete an activity, and how to render it.

When an [activity](https://docs.kwugwo.africa/ugwo/activity-object.md) is `requires_action`, its
`next_action` tells you what the customer has to do: transfer to an
account, dial a USSD code, approve a debit at their bank, or give you
an OTP/PIN to [submit](https://docs.kwugwo.africa/ugwo/submit-next-action.md).

A next action is its own object with an ID, a status and an expiry. An
activity can go through several in sequence (for example
`input_pin` → `input_otp`); `activity.next_action` is always the
current one, and [List next actions](https://docs.kwugwo.africa/ugwo/list-next-actions.md) returns
the history.

> [!TIP]
>
> Using the [embedded checkout](https://docs.kwugwo.africa/checkout-embed.md)? It renders every next
> action for you. This page is for [direct API
> integrations](https://docs.kwugwo.africa/guides/accept-payment-api.md).

## Attributes

**uid** `string`

Unique identifier, `uac.XXXX.YYYYYYYYYYYYYYYYYYYYYYYY`. The
`ugwo.activity.next_action.*` webhooks identify themselves with it.

**action** `object`

The instruction. `action.type` decides the remaining keys. See
[Action types](#action-types).

**status** `enum`

`pending` while the customer still has to act, `fulfilled` once done,
`expired` once it can no longer be completed. See [Status](#status).

**last\_error** `enum | null`

Why the last [input submission](https://docs.kwugwo.africa/ugwo/submit-next-action.md) was
rejected: `invalid_input` (wrong OTP/PIN; ask the customer again) or
`unknown_error_try_again` (temporary failure; resubmit). `null` if
the last submission succeeded or none has been made.

**expires\_at** `string | null`

When the action stops being usable, ISO-8601. `null` if it doesn't
expire. Show a countdown for bank transfers.

**created\_at** `string`

ISO-8601 timestamp.

**updated\_at** `string`

ISO-8601 timestamp.

## Action types

**user\_action**

**Show the customer instructions.** Used by `bank_transfer` and
`ussd`. Nothing to submit; the activity completes when the
customer acts and the PSP confirms.

**type** `string`

`user_action`

**instruction** `string`

Display-ready sentence.

**headers** `object`

The same information as discrete fields, for your own UI. Keys
depend on the medium:

* `bank_transfer`: `bank_name`, `account_number`, `account_name`, `expires_at`
* `ussd`: `ussd` (the code to dial)

```json bank_transfer theme={"system"}
{
  "type": "user_action",
  "instruction": "Transfer to bank",
  "headers": {
    "bank_name": "Test Bank",
    "account_number": "1260881821",
    "account_name": "PAYSTACK CHECKOUT",
    "expires_at": "2026-05-14T20:10:50+00:00"
  }
}
```

```json ussd theme={"system"}
{
  "type": "user_action",
  "instruction": "Please dial *737*33*4*92811# on your mobile phone to complete the transaction",
  "headers": { "ussd": "*737*33*4*92811#" }
}
```

**open\_url**

**Send the customer to a URL.** Used by `pay_with_bank`: the
customer approves the debit at their bank or wallet.

**type** `string`

`open_url`

**url** `string`

Where to send the customer.

**headers** `object`

Context to show next to the button so the customer can confirm the
account, e.g. `account_number` and `account_name`. `account_name`
is the bank's name for the account, and is filled only when it
fairly matches the `account_name_fragment` you sent; otherwise it is
`null`. Keys vary by provider; render defensively.

**iframe** `boolean`

`true` if the URL may be shown in an iframe. When `false` you
**must** use a full redirect or a new window.

**expires\_at** `string | null`

When the URL stops working.

```json theme={"system"}
{
  "type": "open_url",
  "url": "https://checkout.paystack.com/kzp7bxu1lfhy3s2",
  "headers": {
    "account_name": "ADA OKONKWO",
    "account_number": "8012345678"
  },
  "iframe": true,
  "expires_at": "2026-08-12T10:34:11+00:00"
}
```

**input\_otp**

**Collect a one-time password** the customer received from their
bank or wallet, then [submit it](https://docs.kwugwo.africa/ugwo/submit-next-action.md).

**type** `string`

`input_otp`

**supports\_resend** `boolean`

If `true`, you can offer a "Resend code" button: submit
`{ "otp": null }` to send a new code.

```json theme={"system"}
{ "type": "input_otp", "supports_resend": true }
```

Submit: `{ "otp": "123456" }` (string, up to 10 characters).

**input\_pin**

**Collect the customer's 4-digit PIN** and
[submit it](https://docs.kwugwo.africa/ugwo/submit-next-action.md).

```json theme={"system"}
{ "type": "input_pin" }
```

Submit: `{ "pin": "1234" }` (string, exactly 4 digits).

**input\_bvn**

**Collect the customer's Bank Verification Number** and
[submit it](https://docs.kwugwo.africa/ugwo/submit-next-action.md).

```json theme={"system"}
{ "type": "input_bvn" }
```

Submit: `{ "bvn": "22212345678" }` (string, exactly 11 digits).

**input\_birthday**

**Collect the customer's date of birth** and
[submit it](https://docs.kwugwo.africa/ugwo/submit-next-action.md).

```json theme={"system"}
{ "type": "input_birthday" }
```

Submit: `{ "birthday": "1990-04-21" }` (`YYYY-MM-DD`).

> [!WARNING]
>
> New action types may be added. If you build your own UI, handle an
> unknown `action.type` gracefully, for example by falling back to the
> [embedded checkout](https://docs.kwugwo.africa/checkout-embed.md).

## Status

| Status | Meaning |
| - | - |
| `pending` | The customer still has to act. For `input_*` types, submissions are accepted. |
| `fulfilled` | Done. The activity has moved on (it may now have a new `next_action`). |
| `expired` | Can no longer be completed. The activity is usually `expired` or `failed` too. |

```json The Next action object theme={"system"}
{
  "uid": "uac.VCvr.Rk4mZpQ7wLsD2vT8xNbHyCeU",
  "action": {
    "type": "input_otp",
    "supports_resend": true
  },
  "status": "pending",
  "last_error": null,
  "expires_at": "2026-08-12T10:34:11+00:00",
  "created_at": "2026-08-12T10:24:11+00:00",
  "updated_at": "2026-08-12T10:24:11+00:00"
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.