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

# Transaction Object

> The common envelope returned by every single-record GET and embedded in webhooks and statement entries.

Every `GET /{resource}/{id}` response and every webhook payload uses this envelope. The `attributes` object varies by process — see the per-resource pages for full field tables.

## Shape

```json theme={null}
{
  "version": "v2",
  "end2end": "NOXabc123",
  "created_at": "2024-05-01T12:00:00Z",
  "updated_at": "2024-05-01T12:01:00Z",
  "process": "pix_deposit.awaiting_payment",
  "status": {
    "en": "Pending",
    "pt": "Pendente",
    "es": "Pendiente"
  },
  "substatus": {
    "en": "Awaiting Payment",
    "pt": "Aguardando Pagamento",
    "es": "Esperando Pago"
  },
  "message": {
    "en": "QR code generated; awaiting customer payment confirmation",
    "pt": "QR code gerado; aguardando confirmação de pagamento do cliente",
    "es": "Código QR generado; esperando la confirmación de pago del cliente"
  },
  "error_message": { "en": "", "pt": "", "es": "" },
  "attributes": { }
}
```

## Fields

| Field           | Type   | Description                                                                                                                                                                                                  |
| --------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `version`       | string | Envelope label. Not the API version — see the note below                                                                                                                                                     |
| `end2end`       | string | Unique transaction identifier (`NOX...`). This is the `{id}` used by the single-record routes                                                                                                                |
| `created_at`    | string | RFC 3339 creation timestamp                                                                                                                                                                                  |
| `updated_at`    | string | RFC 3339 timestamp of the most recent attribute write. Equal to `created_at` until an attribute is actually rewritten                                                                                        |
| `process`       | string | Machine-readable code for the stage the transaction is currently in, as `stage.state` — e.g. `pix_deposit.awaiting_payment`, `otc_quote.active`, `success.completed`. It changes as the transaction advances |
| `status`        | object | Broad status label, `{ "en": …, "pt": …, "es": … }`                                                                                                                                                          |
| `substatus`     | object | Step-level status label, same three languages                                                                                                                                                                |
| `message`       | object | Explanatory message for the current state                                                                                                                                                                    |
| `error_message` | object | Populated only in a failure state — a waiting state carries no error                                                                                                                                         |
| `attributes`    | object | All visible fields for this transaction — varies by process                                                                                                                                                  |

<Note>
  Internal process machinery — the component, its raw state, and the template name — is deliberately not part of this contract and never appears in a response. Drive your integration from `status` and `substatus`.
</Note>

<Warning>
  **`process` is a stage code, not a resource type.** It tells you where a transaction is, not what kind it is, and some values — `success.completed`, for instance — are shared across products. Do not use it to decide how to parse `attributes`. Use the endpoint you called, and where one endpoint can return more than one shape, branch on which attribute keys are present.
</Warning>

## Reading the envelope correctly

**The four label objects are always present.** When a state has no registered label, `status`, `substatus`, `message`, and `error_message` come back as `{"en": "", "pt": "", "es": ""}` — present with empty strings, not omitted. Treat an empty string as "no information"; do not expect the key to be missing.

**`attributes` is always an object.** When a process has no published attribute schema you get `{}`, not a missing field or `null`.

**An attribute with an empty value is omitted from `attributes`.** A missing key means "not filled in yet" — that is how you distinguish "hasn't happened" from "happened with a zero value". Check for key presence, not for a falsy value.

### `version` is a label, not an API version

The field carries a literal per route, and the ramp routes still emit `"v1"`:

| Route                       | `version` |
| --------------------------- | --------- |
| `/v2/crossramp_checkout[s]` | `"v2"`    |
| `/v2/withdrawal[s]`         | `"v2"`    |
| `/v2/rfq/{id}`              | `"v2"`    |
| `/v2/onramp[s]`             | `"v1"`    |
| `/v2/offramp[s]`            | `"v1"`    |

All of these are `/v2/` routes on the same contract. The value is an inherited label — do not branch on it.

## List responses

All list endpoints (`GET /v2/crossramp_checkouts`, `GET /v2/onramps`, etc.) return the same transaction objects inside a `results` array, wrapped in a pagination envelope:

```json theme={null}
{
  "version": "v2",
  "total": 42,
  "limit": 20,
  "offset": 0,
  "results": [ ]
}
```

`total` is the match count *without* pagination applied, so you can use it to page through the full set. `results` is never `null` — an empty page is `[]`. Items inside `results` carry every field above except `version`.

Lists are always ordered by creation time, newest first. The ordering is not configurable.

## Webhooks

Webhooks deliver the same JSON object as the corresponding `GET /{resource}/{id}` endpoint. Configure the webhook URL per-transaction at creation time or per-template in the dashboard.
