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

# Incentives console reference

> The /marketing/incentives console end to end: the shared reward ledger columns and filters, the issue dialog and the Redeem and Void actions, the role gates on reads and writes, and the API calls behind each control.

# Incentives

The Incentives console at `/marketing/incentives` is the shared reward ledger. Every reward your workspace hands out — referral payouts, loyalty redemptions, and one-off promos you mint directly — lands here as one record with a lifecycle of `issued`, then `redeemed` or `voided`. The [marketing hub overview](/marketing/overview) positions this console against the other three; the [Incentives ledger guide](/guides/incentives-ledger) covers standalone promos and auditing in depth.

Incentives is a tenant-owned control. The ledger only contains rewards someone in your workspace issued, and the one-off issue path exists precisely so you can mint a reward with no program rule behind it.

## What you see on the page

**Issued incentives.** One table, newest first:

| Column | What it tells you |
| - | - |
| **Recipient** | The contact id or, when the reward went to an address instead, the recipient email |
| **Reward** | The reward type, and the code underneath when the reward carries one |
| **Status** | `issued`, `redeemed`, or `voided` — the whole lifecycle |
| **Amount** | The value as issued, formatted for your locale |
| **Source** | Where the reward came from: a referral program, a loyalty redemption, or the standalone issue path |
| **Issued** | When the record was minted |
| **Redeem** / **Void** | The lifecycle actions, enabled only while the row is `issued` |

**Filters.** A **Status** filter (All, Issued, Redeemed, Voided) and a **Contact ID** input with **Apply**, to audit everything one member has been handed. The table pages 25 rows at a time with **Previous** and **Next**.

**Issue incentive.** The header button opens the issue dialog:

* **Reward type** — **Discount code**, **Gift card**, **Custom / manual**, or **Account credit**
* **Reward source** — where a code-backed reward draws its code from, or automatic
* **Contact ID** or **Recipient email** — one of the two identifies the recipient
* **Amount** and **Currency** for value-bearing types
* **Reference (optional)** — an order id, ticket id, or campaign to attach to the record

## Who can read and who can act

| Surface | Read | Write |
| - | - | - |
| Dashboard console | Workspace roles **owner**, **admin**, or **developer** | The same roles: issue, redeem, void |
| Incentives API | Any authenticated key or session | `issue`, `redeem`, and `void` require role **owner**, **admin**, or **developer** |

The dashboard matches the API's write gate, so a role that can see the ledger in the console can also act on it, while a plain authenticated API key can read the ledger and receives a `403` on writes.

## Worked examples

### Mint a one-off support credit

1. Choose **Issue incentive**.
2. Set **Reward type** to **Account credit**, enter the amount and currency, and set the member's **Contact ID**.
3. Put the ticket number in **Reference** so the ledger row is traceable later.
4. Confirm. The row appears with status `issued` and source marking the standalone path.

### Redeem versus void a standing reward

* Choose **Redeem** on an `issued` row to mark the reward used. The confirmation warns this cannot be undone.
* Choose **Void** to cancel a reward you no longer want redeemable, for example a credit issued to the wrong contact. Voided rows stay in the ledger so the audit trail holds.

Both actions leave the row in place and move only the status, which is what makes the table an audit surface.

### Audit one member's rewards

1. Put the member's id in **Contact ID** and choose **Apply**.
2. Switch **Status** to **Issued** to see what they still hold, or to **Redeemed** to see what they actually used.
3. A promotion that shows many `issued` and few `redeemed` rows is an offer that did not convert; the source column tells you which program or one-off mint produced it.

## API pairing

The issue dialog writes `POST /api/v1/incentives/issue`:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.orbit.devotel.io/api/v1/incentives/issue \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "reward_type": "custom",
      "source_ref": "ticket-4821",
      "recipient": { "contact_id": "cnt_member_9x2" },
      "amount": 100,
      "metadata": { "reason": "win-back" },
      "idempotency_key": "winback-cnt_member_9x2"
    }'
  ```

  ```typescript Node.js theme={null}
  import { Orbit } from "@devotel-orbit/node";

  const orbit = new Orbit({ apiKey: process.env.ORBIT_API_KEY! });

  const { data: reward } = await orbit.request<{
    id: string;
    status: "issued" | "redeemed" | "voided";
  }>("POST", "/incentives/issue", {
    body: {
      reward_type: "custom",
      source_ref: "ticket-4821",
      recipient: { contact_id: "cnt_member_9x2" },
      amount: 100,
      metadata: { reason: "win-back" },
      idempotency_key: "winback-cnt_member_9x2",
    },
  });

  console.log(reward.id, reward.status); // issued → redeemed | voided
  ```
</CodeGroup>

The `idempotency_key` makes a retry of the same mint safe. Redeem and void map to `POST /api/v1/incentives/:id/redeem` and `POST /api/v1/incentives/:id/void`, the same calls the row buttons make.

## Tenant-owned controls

Reward types, amounts, recipients, references, and every redeem or void decision are yours. The platform records and enforces the lifecycle; it never issues, redeems, or voids on your behalf.


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