# Transactions

## Create Transaction

Creates a new transaction with one or more journal entries. All journal entries execute atomically.

```
POST /transaction
```

### Headers

| Header            | Required | Description                                     |
| ----------------- | -------- | ----------------------------------------------- |
| `Idempotency-Key` | Yes      | Unique key for this transaction (max 100 chars) |

### Request

```json
{
  "journal_entries": [
    {
      "sequence": 1,
      "type": "PIX_OUT",
      "asset": "BRL",
      "amount": 1000,
      "debit": {
        "account_id": "019702a0-...-debit",
        "balance_policy": "ALWAYS_POSITIVE"
      },
      "credit": {
        "account_id": "019702a0-...-credit",
        "balance_policy": "ALWAYS_NEGATIVE"
      }
    }
  ]
}
```

#### Journal Entry Fields

| Field                   | Type    | Required | Description                                        |
| ----------------------- | ------- | -------- | -------------------------------------------------- |
| `sequence`              | Integer | Yes      | Position in the transaction (starts at 1, no gaps) |
| `type`                  | String  | Yes      | Journal entry type label (e.g., `PIX_OUT`, `FEE`)  |
| `asset`                 | String  | Yes      | Currency code (e.g., `BRL`)                        |
| `amount`                | Integer | Yes      | Amount to move (must be > 0)                       |
| `debit.account_id`      | UUID    | Yes      | Account to debit                                   |
| `debit.balance_policy`  | String  | Yes      | Policy for the debit side                          |
| `credit.account_id`     | UUID    | Yes      | Account to credit                                  |
| `credit.balance_policy` | String  | Yes      | Policy for the credit side                         |

#### Validation Rules

* `sequence` must start at 1 and increment without gaps
* `type` and `asset` accept only `A-Z`, `0-9`, `_` (auto-uppercased)
* `amount` must be greater than 0
* `balance_policy` must be `ALWAYS_POSITIVE`, `ALWAYS_NEGATIVE`, or `NONE`
* Both debit and credit accounts must have the same `asset` as the journal entry's declared `asset`

### Response — `201 Created`

```json
{
  "transaction_id": "019702a0-...-txid",
  "journal_entries": [
    {
      "id": "019702a0-...-entry1",
      "sequence": 1,
      "type": "PIX_OUT",
      "asset": "BRL",
      "amount": 1000,
      "debit": {
        "post_balance": 4000,
        "version": 5
      },
      "credit": {
        "post_balance": -6000,
        "version": 3
      }
    }
  ]
}
```

The response includes `post_balance` and `version` for both sides, allowing you to track balance changes in real time.

### Errors

| HTTP | Code                        | Cause                                                         |
| ---- | --------------------------- | ------------------------------------------------------------- |
| 400  | `INVALID_FIELD`             | Invalid field value (empty, wrong characters)                 |
| 400  | `INVALID_SEQUENCE`          | Sequence must start at 1 and increment without gaps           |
| 400  | `INVALID_BALANCE_POLICY`    | Unknown balance policy value                                  |
| 404  | `ACCOUNT_NOT_FOUND`         | One or more account IDs do not exist                          |
| 409  | `DUPLICATE_IDEMPOTENCY_KEY` | Key already used within the idempotency window                |
| 409  | `INTEGRITY_VIOLATION`       | An involved account has a row-level integrity violation       |
| 422  | `INSUFFICIENT_FUNDS`        | `ALWAYS_POSITIVE` policy violated (balance would go < 0)      |
| 422  | `INVALID_BALANCE`           | `ALWAYS_NEGATIVE` policy violated (balance would go > 0)      |
| 422  | `ASSET_MISMATCH`            | Journal entry asset doesn't match one of the account's assets |

### Example

```bash
curl -X POST http://<host>:8080/transaction \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: ak_..." \
  -H "X-Api-Secret: sk_..." \
  -H "Idempotency-Key: payment-abc-123" \
  -d '{
    "journal_entries": [
      {
        "sequence": 1,
        "type": "PIX_IN",
        "asset": "BRL",
        "amount": 5000,
        "debit": {"account_id": "...", "balance_policy": "NONE"},
        "credit": {"account_id": "...", "balance_policy": "NONE"}
      }
    ]
  }'
```

***

## Get Transaction

Retrieves all journal entries of a transaction.

```
GET /transaction/:id
```

### Response — `200 OK`

```json
{
  "transaction_id": "019702a0-...-txid",
  "journal_entries": [
    {
      "id": "019702a0-...-entry1",
      "sequence": 1,
      "type": "PIX_OUT",
      "asset": "BRL",
      "amount": 1000,
      "debit": { ... },
      "credit": { ... },
      "created_at": "2026-01-15T10:30:00.123Z"
    }
  ]
}
```

### Errors

| HTTP | Code                    | Cause                                  |
| ---- | ----------------------- | -------------------------------------- |
| 404  | `TRANSACTION_NOT_FOUND` | No journal entries found for this UUID |

***

## Get Journal Entry

Retrieves a specific journal entry by ID.

```
GET /journal/entry/:id
```

### Response — `200 OK`

```json
{
  "id": "019702a0-...-entry1",
  "transaction_id": "019702a0-...-txid",
  "sequence": 1,
  "type": "PIX_OUT",
  "asset": "BRL",
  "amount": 1000,
  "debit": {
    "account_id": "...",
    "category": "PAYMENT_ACCOUNT",
    "post_balance": 4000,
    "version": 5,
    "balance_policy": "ALWAYS_POSITIVE"
  },
  "credit": {
    "account_id": "...",
    "category": "PIX_ASSET",
    "post_balance": -6000,
    "version": 3,
    "balance_policy": "ALWAYS_NEGATIVE"
  },
  "idempotency_key": "payment-abc-123",
  "created_at": "2026-01-15T10:30:00.123Z"
}
```

### Errors

| HTTP | Code                      | Cause                             |
| ---- | ------------------------- | --------------------------------- |
| 404  | `JOURNAL_ENTRY_NOT_FOUND` | Journal entry UUID does not exist |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://entrytarget.gitbook.io/docs/api-reference/transactions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
