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

# Connector behaviour

> Status values, error responses, timing, limits, and the request constraints that apply to every connector.

Connectors accept your vendor's request shape and return your vendor's response shape. A few things are Fluz's rather than the vendor's, and they are the same across all three gift card connectors. Read this page before you cut over.

## Authentication and account scope

Every connector uses HTTP Basic authentication with your Fluz API key:

```text theme={null}
Authorization: Basic <FLUZ-API-Key>
```

A key is issued for exactly one Fluz account. That account funds every order placed with the key, and every read is scoped to it.

Fields your vendor used to route between sub-accounts, such as Tango's `accountIdentifier`, do not select a sub-account here. If you operate several accounts, request one key per account.

## Order status values

The `status` field on an order (`OrderStatus` on InComm) carries a Fluz value, not your vendor's:

| Status        | Meaning                          |
| :------------ | :------------------------------- |
| `PENDING`     | Accepted, not started            |
| `IN_PROGRESS` | Being fulfilled                  |
| `COMPLETED`   | Fulfilled, credentials available |
| `FAILED`      | Not fulfilled                    |
| `CANCELED`    | Cancelled before fulfilment      |

<Callout icon="⚠️">
  Your vendor's status strings do not carry over. A check written against a vendor value, for example `status === "COMPLETE"`, will not match `COMPLETED`. Update every status comparison before you cut over.
</Callout>

## Timing

**Tango Card and InComm** create an order synchronously, always running to completion. The call does not return until the purchase has finished, which can take up to 150 seconds, so set your client's read timeout above that.

**Runa** is asynchronous by default. `POST /v2/order` returns `202` immediately with a reference ID, and you read the order later. Send `X-Execution-Mode: sync` to block until the purchase completes and receive the full result, as Tango and InComm do.

## Reading an order

An order becomes readable once its purchase has completed. Reading a reference ID before then returns an error rather than a pending status, so treat an error on a freshly created asynchronous order as still processing and read again shortly.

The list endpoints return the 100 most recent orders on the account in a single response, newest first.

## Error responses

Errors use the Fluz envelope, not your vendor's error schema:

```json theme={null}
{ "error": "<message>" }
```

| Code  | When                                                                |
| :---- | :------------------------------------------------------------------ |
| `401` | Missing or invalid credentials                                      |
| `429` | Rate limit exceeded. Body is `{ "message": "Rate limit exceeded" }` |
| `500` | Every other failure, including a request the connector rejects      |

A rejected request and a server fault both return `500`. Read the `error` message to tell them apart: a rejection means the request needs to change, a fault is safe to retry.

## Rate limits

20 requests per second, applied per API key and per source IP. Exceeding either limit blocks that key or IP for 10 seconds, so back off for at least that long after a `429`.

The per-key limit is shared, so several hosts using one key share one budget.

## Balances

A balance read reports the available balance of the Fluz account your API key is issued for. Tango returns it as `currentBalance` and Runa as `balance`; InComm returns `availableBalance` alongside `prepaidBalance`, which covers the gift card balance on its own.

A balance read is always scoped to the account your key is issued for, so the discriminators in your vendor's balance calls do not narrow it further: Tango's `:accountId`, InComm's `:programId` and Runa's `?currency=` are accepted for compatibility with your existing request shape.

One behaviour to watch: a balance call with any query string returns a single object, and a call with none returns an array of one. If your client calls `.map()` over the response, keep the query string off.

## Brand codes

All three connectors resolve brand codes against one Fluz catalog, whichever field carries them: `utid` on Tango, `Sku` on InComm, `items[].products.value` on Runa. Your vendor's product codes do not carry over, and a code Fluz does not recognise returns an error.

<Callout icon="⚠️">
  Map your full brand list against the Fluz catalog before you cut over. A code that resolves to the wrong Fluz offer delivers the wrong card without an error.
</Callout>

## Request constraints

Connectors accept your vendor's request shape, but some values are fixed. A request that breaks one of these is rejected.

| Connector  | Constraint                                                                                               |
| :--------- | :------------------------------------------------------------------------------------------------------- |
| Tango Card | `sendEmail` must be present and set to `false`                                                           |
| Runa       | `payment_method` must be `{ "type": "ACCOUNT_BALANCE", "currency": "USD" }`                              |
| Runa       | `products.type` must be `SINGLE`                                                                         |
| Runa       | Every entry in `items[]` must be identical. Mixed baskets are rejected. Send one order per distinct item |
| InComm     | Exactly one entry in `Recipients[]`                                                                      |
| InComm     | Exactly one entry in `Products[]`                                                                        |
| InComm     | `DeliverEmail` must not be `true`                                                                        |

Fluz returns gift card credentials directly in the order response, which is why the email flags above must be off: delivery to the recipient stays under your control.
