Documentation

Rewards & triggers

Define reward templates, redeem them, and automate issuance with triggers.

A reward template defines what can be issued — points plus optional content (a badge, certificate, coupon, or attachment). You issue it by redeeming it to a recipient, either directly or automatically via a trigger. All paths are under https://api.davi.social/api/v1; org actions use an org-scoped token.

1. Create a reward template

curl -X POST "https://api.davi.social/api/v1/organizations/ORG_SLUG/rewards" \
  -H "Authorization: Bearer ORG_SCOPED_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Check-in Badge",
    "points": 100,
    "supply_total": null,
    "content_config": { "storage_type": "platform" }
  }'

Fields: name, points (required), optional description, category, activity_uuid (link to an event), and supply_total (null = unlimited). The content_config.storage_type controls how content is produced:

  • platform — Davi renders the content from content_template.
  • external — your webhook generates it (external_webhook_uuid); redemptions are asynchronous.
  • dynamic — reserved for per-recipient generation. Variable interpolation is being reworked and isn't currently dependable — prefer platform or external.

Templates start as drafts. Move one through its lifecycle by PATCHing its statuspublished makes a draft live, draft returns it to draft (only while it has no redemptions), and archived withdraws it:

curl -X PATCH "https://api.davi.social/api/v1/rewards/REWARD_SLUG" \
  -H "Authorization: Bearer ORG_SCOPED_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "status": "published" }'

Scopes: reward:create to create, reward:manage to update / publish.

2. Redeem a reward

Issue the reward to a recipient with POST /rewards/{reward_slug}/redeem (scope reward:redeem):

curl -X POST "https://api.davi.social/api/v1/rewards/REWARD_SLUG/redeem" \
  -H "Authorization: Bearer ORG_SCOPED_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "identifier": { "type": "username", "value": "ada" },
    "scope": "single-use",
    "idempotency_key": "unique-per-redemption"
  }'

Recipients

The identifier is an IdentifierRef{ "type": …, "value": … } where type is one of card, wallet, username, user_id, or link. This resolves even to a custodial wallet for someone without a Davi account yet.

Sync vs. async results

  • Completed (platform/dynamic): { "status": "completed", "transaction_id": … }.
  • Pending (external): { "status": "pending", "delivery_uuid": … } — poll GET /rewards/deliveries/{delivery_uuid} until it reports completed (with a transaction_id) or failed.

The recipient reads the issued content via GET /rewards/transactions/{transaction_id}.

3. Automate with triggers

Instead of redeeming by hand, a reward trigger issues a template automatically when a matching event occurs. Create one with POST /organizations/{organization_slug}/reward-triggers (scope reward:manage):

curl -X POST \
  "https://api.davi.social/api/v1/organizations/ORG_SLUG/reward-triggers" \
  -H "Authorization: Bearer ORG_SCOPED_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Reward 5 check-ins",
    "reward_template_uuid": "REWARD_UUID",
    "trigger_scopes": ["activity.checked_in:count:5"],
    "deduplication_window_seconds": 300
  }'
  • trigger_scopes are patterns describing the condition, e.g. activity.checked_in:count:5 (the 5th check-in) or activity.registered:first. These are unrelated to OAuth scopes.
  • deduplication_window_seconds prevents the same trigger from firing twice for a user within the window (default 300; null to disable).

When an activity check-in matches, Davi issues the reward to that user automatically.

Next