Complete Endpoint Reference.
Every agent API endpoint across all roles — routes, methods, scopes, parameters, and response fields. The full picture.
Complete Endpoint Reference
Every agent API endpoint, read from source. Base URL: /api/agent/v1 (69 endpoints total).
All endpoints require a valid agent key via the X-Agent-Key header. See Authentication for details.
💡 Interactive version available: Browse the full OpenAPI spec in Swagger UI → or download the raw JSON spec for import into Postman or code generators. For machine-readable tool definitions, see Tool Discovery.
Global
Health Check
GET /health
Scope: Any valid key (no specific scope required) Role: All (partner, member, admin)
Returns key identity, scopes, rate limit, and connectivity status.
Response fields: status, key.name, key.prefix, key.role, key.scopes[], key.rate_limit, key.expires_at, key.created_at, key.last_used_at, owner.id, owner.name, owner.type
Tool Discovery
GET /tools
Scope: Any valid key (no specific scope required) Role: All (partner, member, admin)
Returns machine-readable tool definitions scoped to the authenticated key's role and permissions. Pass ?format=openai, ?format=anthropic, ?format=mcp, or ?format=generic (default) to get definitions in your agent framework's format.
This endpoint is excluded from its own tool list — a tool that lists tools is meta-noise for agents.
Query parameters: format (string, default: generic)
Response fields: tools[], meta.role, meta.format, meta.tool_count, meta.cached
See Tool Discovery for full format examples and integration guides.
Partner Endpoints
All partner endpoints are prefixed with /partner and require a partner agent key.
Clubs
Clubs are organizational units that group cards, staff, and tiers.
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/partner/clubs |
read or write:clubs |
List all clubs |
GET |
/partner/clubs/{id} |
read or write:clubs |
Get club detail |
POST |
/partner/clubs |
write:clubs |
Create a club |
PUT |
/partner/clubs/{id} |
write:clubs |
Update a club |
DELETE |
/partner/clubs/{id} |
write:clubs |
Delete a club |
Create/Update body:
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | ✅ create | Max 120 chars |
is_active |
boolean | — | Default true |
Guards: Protected clubs (is_undeletable) cannot be deleted.
Loyalty Cards
Cards define the points economy: currency, earning rate, limits, expiry.
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/partner/cards |
read or write:cards |
List all loyalty cards |
GET |
/partner/cards/{id} |
read or write:cards |
Get card detail |
POST |
/partner/cards |
write:cards |
Create a loyalty card |
PUT |
/partner/cards/{id} |
write:cards |
Update a loyalty card |
DELETE |
/partner/cards/{id} |
write:cards |
Delete a loyalty card |
Create body:
| Field | Type | Required | Notes |
|---|---|---|---|
club_id |
UUID | ✅ | Must belong to this partner |
name |
string | ✅ | Max 250 chars |
head |
string/json | — | Translatable heading |
title |
string/json | — | Translatable title |
description |
string/json | — | Translatable description |
currency |
string | ✅ | ISO 4217 (3 chars, e.g. EUR) |
points_per_currency |
number | ✅ | Points earned per currency unit (0–100000) |
currency_unit_amount |
number | ✅ | Currency unit size (1–1000000) |
min_points_per_purchase |
number | ✅ | Min points per transaction (0–10M) |
max_points_per_purchase |
number | ✅ | Max points per transaction (0–10M) |
initial_bonus_points |
number | — | Bonus on first interaction |
points_expiration_months |
number | ✅ | Months before points expire (1–1200) |
issue_date |
date | — | When the card becomes active |
expiration_date |
date | — | When the card expires |
is_active |
boolean | — | Default true |
is_visible_by_default |
boolean | — | Show on homepage |
bg_color |
hex color | — | Background color (e.g. #FF5733) |
bg_color_opacity |
number | — | Opacity 0–100 |
text_color |
hex color | — | Text color |
Update: All fields optional. club_id can be changed (ownership verified).
Permission gate: loyalty_cards_permission
Limit gate: loyalty_cards_limit
Rewards
Redeemable items that members exchange points for.
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/partner/rewards |
read or write:rewards |
List all rewards |
GET |
/partner/rewards/{id} |
read or write:rewards |
Get reward detail |
POST |
/partner/rewards |
write:rewards |
Create a reward |
PUT |
/partner/rewards/{id} |
write:rewards |
Update a reward |
DELETE |
/partner/rewards/{id} |
write:rewards |
Delete a reward |
Create body:
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | ✅ | Max 120 chars |
title |
string/json | — | Translatable |
description |
string/json | — | Translatable |
points |
number | ✅ | Cost in points (0–10M) |
active_from |
date | — | When the reward becomes active |
expiration_date |
date | — | When the reward expires |
is_active |
boolean | — | Default true |
Permission gate: loyalty_cards_permission
Limit gate: rewards_limit
Transactions
The core earn-and-burn flow for POS/CRM integrations.
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/partner/transactions |
read or write:transactions |
List transactions |
POST |
/partner/transactions/purchase |
write:transactions |
Record purchase → award points |
POST |
/partner/transactions/redeem |
write:rewards |
Redeem reward → deduct points |
List Transactions
GET /partner/transactions
Query parameters:
| Parameter | Type | Description |
|---|---|---|
member_identifier |
string | Filter by member (UUID, email, or unique_identifier) |
card_id |
UUID | Filter by loyalty card |
event |
string | Filter by event type |
from |
date | Start date (Y-m-d) |
to |
date | End date (Y-m-d) |
per_page |
int | Results per page (default 25, max 100) |
Response per item: id, event, points, purchase_amount, currency, member_id, card_id, reward_id, staff_id, staff_name, note, expires_at, created_at
Record a Purchase
POST /partner/transactions/purchase
| Field | Type | Required | Notes |
|---|---|---|---|
card_id |
UUID | ✅ | Must belong to this partner |
member_identifier |
string | ✅ | UUID, email, member_number, or unique_identifier |
purchase_amount |
number | ✅† | Required if points not set. Min 0.01 |
points |
integer | — | Override automatic calculation |
staff_id |
UUID | — | Attribute to staff member. If omitted, attributed to "System" |
note |
string | — | Max 500 chars |
† Either purchase_amount or points must be provided.
Response: transaction_id, points_awarded, member_balance, purchase_amount, card_id, member_id
Redeem a Reward
POST /partner/transactions/redeem
| Field | Type | Required | Notes |
|---|---|---|---|
card_id |
UUID | ✅ | Must belong to this partner |
reward_id |
UUID | ✅ | Must belong to this partner |
member_identifier |
string | ✅ | UUID, email, member_number, or unique_identifier |
staff_id |
UUID | — | If omitted, uses system-level redemption |
note |
string | — | Max 500 chars |
Response: transaction_id, points_deducted, member_balance, new_balance, reward_id, reward.id, reward.title, card_id, member_id
Members
Read-only member access for partners. Members self-register or are auto-enrolled via transactions.
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/partner/members |
read |
List members who've interacted with your cards |
GET |
/partner/members/{id} |
read |
Get member detail |
GET |
/partner/members/{id}/balance/{cardId} |
read |
Get member's point balance on a card |
List query parameters:
| Parameter | Type | Description |
|---|---|---|
search |
string | Search by name, email, member_number, or unique_identifier |
per_page |
int | Results per page |
Show: The {id} parameter accepts UUID, email, member_number, or unique_identifier.
Member response: id, unique_identifier, name, email, locale, currency, time_zone, last_login_at, created_at, updated_at, avatar, is_anonymous
Balance response: member_id, card_id, balance, currency
Stamp Cards
Digital punch cards. Members collect stamps and earn a reward when complete.
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/partner/stamp-cards |
read or write:stamps |
List stamp cards |
GET |
/partner/stamp-cards/{id} |
read or write:stamps |
Get stamp card detail |
POST |
/partner/stamp-cards |
write:stamps |
Create a stamp card |
PUT |
/partner/stamp-cards/{id} |
write:stamps |
Update a stamp card |
DELETE |
/partner/stamp-cards/{id} |
write:stamps |
Delete a stamp card |
POST |
/partner/stamp-cards/{id}/stamps |
write:stamps |
Add stamps to a member |
POST |
/partner/stamp-cards/{id}/redeem |
write:stamps |
Redeem a pending stamp reward |
Create body:
| Field | Type | Required | Notes |
|---|---|---|---|
club_id |
UUID | ✅ | Must belong to this partner |
name |
string | ✅ | Max 250 chars |
head |
string/json | — | Translatable heading |
title |
string/json | — | Translatable title |
description |
string/json | — | Translatable description |
reward_title |
string/json | — | Translatable reward title |
stamps_required |
integer | ✅ | 1–100 |
stamps_per_purchase |
integer | — | Default 1 |
max_stamps_per_transaction |
integer | — | Limit per transaction |
max_stamps_per_day |
integer | — | Daily limit |
min_purchase_amount |
number | — | Min transaction to earn stamp |
currency |
string | — | ISO 4217 |
stamps_expire_days |
integer | — | Days before stamps expire |
requires_physical_claim |
boolean | — | Require staff to confirm redemption |
is_active |
boolean | — | Default true |
Use canonical field names only: stamps_expire_days and requires_physical_claim.
Permission gate: stamp_cards_permission
Limit gate: stamp_cards_limit
Add Stamps
POST /partner/stamp-cards/{id}/stamps
| Field | Type | Required | Notes |
|---|---|---|---|
member_identifier |
string | ✅ | UUID, email, or unique_identifier |
stamps |
integer | — | Default 1 |
purchase_amount |
number | — | Transaction amount (for min_purchase_amount validation) |
note |
string | — | Max 500 chars |
Response: stamps_added, current_stamps, stamps_required, completed, pending_rewards
Redeem Stamp Reward
POST /partner/stamp-cards/{id}/redeem
| Field | Type | Required | Notes |
|---|---|---|---|
member_identifier |
string | ✅ | UUID, email, or unique_identifier |
note |
string | — | Max 500 chars |
Response: reward_title, reward_value, remaining_rewards
Vouchers
Digital discount vouchers with usage tracking.
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/partner/vouchers |
read or write:vouchers |
List vouchers |
GET |
/partner/vouchers/{id} |
read or write:vouchers |
Get voucher detail |
POST |
/partner/vouchers |
write:vouchers |
Create a voucher |
PUT |
/partner/vouchers/{id} |
write:vouchers |
Update a voucher |
DELETE |
/partner/vouchers/{id} |
write:vouchers |
Delete a voucher |
POST |
/partner/vouchers/validate |
write:vouchers |
Validate a voucher code |
POST |
/partner/vouchers/{id}/redeem |
write:vouchers |
Redeem voucher for a member |
Create body:
| Field | Type | Required | Notes |
|---|---|---|---|
club_id |
UUID | ✅ | Must belong to this partner |
code |
string | — | Max 32 chars. Generated automatically when omitted |
name |
string | ✅ | Max 128 chars |
title |
string/json | — | Translatable |
description |
string/json | — | Translatable |
type |
string | ✅ | percentage, fixed_amount, free_product, or bonus_points |
value |
integer | ✅† | Required unless type is free_product or bonus_points |
points_value |
integer | — | Required when type=bonus_points |
currency |
string | — | ISO 4217 |
min_purchase_amount |
integer | — | Minimum order amount in minor units |
max_discount_amount |
integer | — | Discount cap in minor units |
max_uses_total |
integer | — | Total usage ceiling |
max_uses_per_member |
integer | — | Per-member usage ceiling |
valid_from |
date | — | Voucher becomes redeemable at this time |
valid_until |
date | — | Voucher expires after this time |
is_active |
boolean | — | Default true |
is_public |
boolean | — | Publicly claimable in member flows |
is_single_use |
boolean | — | Single-use voucher flag |
Use canonical field names only: type, value, max_uses_total, valid_from, and valid_until.
Permission gate: vouchers_permission
Limit gate: vouchers_limit
Validate Voucher
POST /partner/vouchers/validate
| Field | Type | Required | Notes |
|---|---|---|---|
code |
string | ✅ | Voucher code |
member_identifier |
string | ✅ | UUID, email, member_number, or unique_identifier |
club_id |
UUID | ✅ | Must belong to this partner |
order_amount |
integer | — | Order amount in minor units |
Response: valid, voucher_id, code, name, type, value, currency, discount_amount, capped, original_amount, final_amount, times_used, remaining_uses, valid_until
Redeem Voucher
POST /partner/vouchers/{id}/redeem
| Field | Type | Required | Notes |
|---|---|---|---|
member_identifier |
string | ✅ | UUID, email, member_number, or unique_identifier |
order_amount |
integer | — | Order amount in minor units |
order_reference |
string | — | External order reference, max 64 chars |
Response: voucher_id, code, type, member_id, discount_amount, points_awarded, remaining_uses, redemption_id
Validation checks: Active, within the validity window, and not exhausted (times_used < max_uses_total when a total cap exists).
Tiers
Loyalty levels within a club (e.g., Bronze, Silver, Gold).
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/partner/tiers |
read or write:tiers |
List tiers |
GET |
/partner/tiers/{id} |
read or write:tiers |
Get tier detail |
POST |
/partner/tiers |
write:tiers |
Create a tier |
PUT |
/partner/tiers/{id} |
write:tiers |
Update a tier |
DELETE |
/partner/tiers/{id} |
write:tiers |
Delete a tier |
Create body:
| Field | Type | Required | Notes |
|---|---|---|---|
club_id |
UUID | ✅ | Must belong to this partner |
name |
string/json | ✅ | Translatable |
description |
string/json | — | Translatable |
level |
integer | ✅ | Sorting order (min 0) |
points_threshold |
integer | — | Points needed to reach this tier |
points_multiplier |
number | — | Earning multiplier (1–100) |
color |
string | — | Hex, max 7 chars |
icon |
string | — | Icon identifier, max 50 chars |
is_default |
boolean | — | Default tier for new members |
is_active |
boolean | — | Default true |
Staff
Staff members who operate loyalty cards (scan, award, redeem).
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/partner/staff |
read or write:staff |
List staff members |
GET |
/partner/staff/{id} |
read or write:staff |
Get staff detail |
POST |
/partner/staff |
write:staff |
Create a staff member |
PUT |
/partner/staff/{id} |
write:staff |
Update a staff member |
DELETE |
/partner/staff/{id} |
write:staff |
Delete a staff member |
Create body:
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | ✅ | Max 120 chars |
email |
string | ✅ | Must be unique across all staff |
password |
string | ✅ | 6–48 chars |
club_id |
UUID | — | Assign to a specific club (ownership verified) |
is_active |
boolean | — | Default true |
Use the canonical field club_id.
Update: All fields optional. email uniqueness enforced excluding current record.
Limit gate: staff_members_limit
Member Endpoints
All member endpoints are prefixed with /member and require a member agent key.
Profile
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/member/profile |
read |
Get own profile |
PUT |
/member/profile |
write:profile |
Update own profile |
Show response: id, name, email, locale, unique_identifier, avatar, is_anonymous, has_interacted, first_interaction_at, created_at
Update body:
| Field | Type | Notes |
|---|---|---|
name |
string | Max 200 chars |
locale |
string | Installed locale code (e.g. en_US, fr_FR) |
Email cannot be changed via API — requires the full auth flow.
Balance & Cards
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/member/balance |
read |
All card balances in one call |
GET |
/member/cards |
read |
List enrolled cards (paginated) |
GET |
/member/cards/{id} |
read |
Get card detail + balance |
Balance response per card: card_id, card_title, balance, currency
Card detail response: id, name, title, description, currency, balance, bg_color, text_color, is_active
Transaction History
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/member/transactions |
read |
All transactions across all cards |
GET |
/member/transactions/{cardId} |
read |
Transactions for a specific card |
Response per transaction: id, card_id, card_title, event, points, points_used, purchase_amount, currency, reward_title, reward_points, note, expires_at, created_at
Member transaction responses are filtered to member-relevant fields only — no partner emails, internal config, or admin metadata.
Rewards
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/member/rewards |
read |
List available rewards on enrolled cards |
POST |
/member/rewards/{id}/claim |
write:redeem |
Submit a reward claim request |
Rewards list response per item: id, title, description, points, image, active_from, expiration_date, can_afford, best_balance, deficit
The can_afford and deficit fields enable "You need X more points" messaging.
Claim: Submits a claim intent — NOT a direct redemption. Staff must confirm via their dashboard or the partner agent API. This prevents fraud in physical locations.
Claim response: status (claim_submitted), reward_id, reward_title, points_required, card_id, card_title, current_balance, message
Discover
Members discover cards via homepage browsing or QR code/shared link scanning.
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/member/discover |
read |
Browse homepage-visible cards |
POST |
/member/discover/resolve |
read |
Resolve a URL/UUID/identifier to a card |
POST |
/member/discover/follow |
write:profile |
Save card to "My Cards" |
POST |
/member/discover/unfollow |
write:profile |
Remove card from "My Cards" |
Browse
Returns all active, visible cards across all partners grouped by type:
Response: data.cards[], data.stamp_cards[], data.vouchers[]
Each item includes type-specific display fields and the member's enrollment/follow status.
Resolve
POST /member/discover/resolve
| Field | Type | Notes |
|---|---|---|
url |
string | A card URL from QR code |
identifier |
string | UUID or unique_identifier (e.g. 344-319-665-971) |
One of url or identifier is required.
Supported URL patterns:
https://example.com/{locale}/card/{uuid}https://example.com/{locale}/stamp-card/{uuid}https://example.com/{locale}/voucher/{uuid}https://example.com/{locale}/follow/{uuid}
Follow / Unfollow
POST /member/discover/follow
POST /member/discover/unfollow
| Field | Type | Required |
|---|---|---|
card_id |
UUID | ✅ |
Follow is idempotent — calling it twice is safe.
Admin Endpoints
All admin endpoints are prefixed with /admin and require an admin agent key.
Partners
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/admin/partners |
read:partners |
List all partners |
GET |
/admin/partners/{id} |
read:partners |
Get partner detail + permissions + usage |
PATCH |
/admin/partners/{id}/permissions |
write:partners |
Update partner permissions & limits |
POST |
/admin/partners/{id}/activate |
write:partners |
Reactivate a partner |
POST |
/admin/partners/{id}/deactivate |
write:partners |
Deactivate a partner |
List query parameters:
| Parameter | Type | Description |
|---|---|---|
is_active |
boolean | Filter by active status |
search |
string | Search by name or email |
per_page |
int | Results per page |
Partner detail response: id, name, email, locale, currency, time_zone, is_active, avatar, created_at, permissions{}, usage{}
Permissions body (all optional):
| Field | Type | Notes |
|---|---|---|
loyalty_cards_permission |
boolean | Allow loyalty cards |
loyalty_cards_limit |
integer | Card limit (-1 = unlimited) |
stamp_cards_permission |
boolean | Allow stamp cards |
stamp_cards_limit |
integer | Stamp card limit |
vouchers_permission |
boolean | Allow vouchers |
voucher_batches_permission |
boolean | Allow voucher batches |
vouchers_limit |
integer | Voucher limit |
rewards_limit |
integer | Reward limit |
staff_members_limit |
integer | Staff limit |
email_campaigns_permission |
boolean | Allow email campaigns |
activity_permission |
boolean | Allow activity logs |
agent_api_permission |
boolean | Allow agent API |
agent_keys_limit |
integer | Agent key limit |
cards_on_homepage |
boolean | Show cards on homepage |
Deactivate invalidates all associated agent keys immediately.
Partners are NOT created/deleted via agent API — they self-register or are managed through the admin dashboard.
Members (Platform-wide)
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/admin/members |
read:members |
List all members platform-wide |
GET |
/admin/members/{id} |
read:members |
Get member detail + card balances |
List query parameters:
| Parameter | Type | Description |
|---|---|---|
search |
string | Search by name, email, or unique_identifier |
is_active |
boolean | Filter by active status |
per_page |
int | Results per page |
Member detail response: id, name, email, unique_identifier, locale, is_active, is_anonymous, created_at, card_balances[]
Each card_balance includes: card_id, card_title, club_name, balance, currency
Read-only. Member lifecycle is managed through transactions (auto-enrollment) or member self-service.
Analytics
| Method | Endpoint | Scope | Description |
|---|---|---|---|
GET |
/admin/analytics/overview |
read:analytics |
Platform-wide metrics |
GET |
/admin/analytics/partners/{id} |
read:analytics |
Per-partner metrics |
Overview response: total_partners, active_partners, total_members, total_cards, total_stamp_cards, total_vouchers, transactions_today, transactions_this_week, transactions_this_month
Per-partner response: partner_id, partner_name, is_active, loyalty_cards, stamp_cards, vouchers, rewards, staff_members, total_transactions, transactions_today, total_members_enrolled
Endpoint Count Summary
| Role | GET | POST | PUT | PATCH | DELETE | Total |
|---|---|---|---|---|---|---|
| Global | 2 | — | — | — | — | 2 |
| Partner | 18 | 13 | 7 | — | 7 | 45 |
| Member | 8 | 4 | 1 | — | — | 13 |
| Admin | 6 | 2 | — | 1 | — | 9 |
| Total | 34 | 19 | 8 | 1 | 7 | 69 |