Amba

Streaks

Manage streak definitions — daily or weekly cadence, grace windows, and optional freezes.

Streak definitions describe the rules that user streaks follow. Per-user streak state is created and updated automatically by the streak evaluator and the POST /client/streaks/:streakId/qualify endpoint.

Endpoints

MethodPathDescription
POST/admin/projects/:projectId/streaksCreate a streak definition.
GET/admin/projects/:projectId/streaksList streak definitions.
PATCH/admin/projects/:projectId/streaks/:streakIdPartial update.
DELETE/admin/projects/:projectId/streaks/:streakIdDelete a streak definition.
POST/admin/projects/:projectId/users/:userId/streaks/:streakDefinitionId/grant-shieldGrant 1+ shields (freezes) to a user streak.

POST /admin/projects/:projectId/streaks

Request

FieldTypeRequiredDefaultDescription
keystringyesStable human-readable identifier (e.g. "daily_workout"). Used by clients to qualify by key. Immutable after creation.
namestringyes
descriptionstringnonull
qualifying_eventstringyesEngagement event that counts toward the streak.
period"daily" | "weekly"no"daily"
grace_period_hoursnumberno0Extra hours after period end before the streak breaks.
freeze_enabledbooleannofalseAllow freezes (shields) to save a streak on a missed period.
max_freezesnumberno1Per-user freeze cap.
freezes_per_n_eventsnumber | nullnonullAuto-grant rule. When set, every N consecutive qualifying events grants 1 freeze, capped at max_freezes.

Response 201

{
  "data": {
    "id": "…",
    "key": "daily_workout",
    "name": "Daily Workout",
    "qualifying_event": "workout_completed",
    "period": "daily",
    "grace_period_hours": 0,
    "freeze_enabled": false,
    "max_freezes": 1,
    "created_at": "…"
  }
}

Try it:

POST/admin/projects/%7B%7BprojectId%7D%7D/streaks
developer auth
curl -X POST 'https://api.amba.dev/v1/admin/projects/%7B%7BprojectId%7D%7D/streaks'
Loading auth… Configure auth in the settings drawer (top-right) to run this request.

Curl:

curl -X POST '${BASE_URL}/admin/projects/{projectId}/streaks' \
  -H 'Authorization: Bearer ${DEV_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{}'

GET /admin/projects/:projectId/streaks

{ "data": [{ "id": "…", "name": "…", "qualifying_event": "…", "period": "daily" }] }

Try it:

GET/admin/projects/%7B%7BprojectId%7D%7D/streaks
developer auth
curl -X GET 'https://api.amba.dev/v1/admin/projects/%7B%7BprojectId%7D%7D/streaks'
Loading auth… Configure auth in the settings drawer (top-right) to run this request.

Curl:

curl -X GET '${BASE_URL}/admin/projects/{projectId}/streaks' \
  -H 'Authorization: Bearer ${DEV_TOKEN}'

PATCH /admin/projects/:projectId/streaks/:streakId

Updatable fields: name, description, qualifying_event, period, grace_period_hours, freeze_enabled, max_freezes, freezes_per_n_events.

key is immutable — it cannot be changed after creation. Clients that qualify by key rely on the key being stable; changing it would silently break their qualify calls.

Errors

  • 404 NOT_FOUND.
  • 500 UPDATE_FAILED.

Try it:

PATCH/admin/projects/%7B%7BprojectId%7D%7D/streaks/%7B%7BstreakId%7D%7D
developer auth
curl -X PATCH 'https://api.amba.dev/v1/admin/projects/%7B%7BprojectId%7D%7D/streaks/%7B%7BstreakId%7D%7D'
Loading auth… Configure auth in the settings drawer (top-right) to run this request.

Curl:

curl -X PATCH '${BASE_URL}/admin/projects/{projectId}/streaks/{streakId}' \
  -H 'Authorization: Bearer ${DEV_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{}'

DELETE /admin/projects/:projectId/streaks/:streakId

{ "data": { "deleted": true } }

Try it:

DELETE/admin/projects/%7B%7BprojectId%7D%7D/streaks/%7B%7BstreakId%7D%7D
developer auth
curl -X DELETE 'https://api.amba.dev/v1/admin/projects/%7B%7BprojectId%7D%7D/streaks/%7B%7BstreakId%7D%7D'
Loading auth… Configure auth in the settings drawer (top-right) to run this request.

Curl:

curl -X DELETE '${BASE_URL}/admin/projects/{projectId}/streaks/{streakId}' \
  -H 'Authorization: Bearer ${DEV_TOKEN}'

POST /admin/projects/:projectId/users/:userId/streaks/:streakDefinitionId/grant-shield

Grant N shields (freezes) to a specific user's streak. Increases freezes_remaining by count, clamped at the streak definition's max_freezes.

The endpoint refuses to provision a user's first-touch streak state — the streak evaluator does that automatically on the user's first qualifying event. Grant-shield is meant for top-ups, not first-touch provisioning.

Request

FieldTypeRequiredDefaultDescription
countnumberno1Positive integer. Clamped at cap.

Response 200

{
  "data": {
    "id": "us_…",
    "app_user_id": "…",
    "streak_definition_id": "…",
    "current_count": 7,
    "freezes_remaining": 2,
    "status": "active",
    "updated_at": "…"
  }
}

Errors

  • 400 INVALID_COUNTcount must be a positive integer.
  • 400 INVALID_IDuserId or streakDefinitionId is not a UUID.
  • 404 STREAK_DEFINITION_NOT_FOUND — no streak definition matches streakDefinitionId.
  • 404 USER_STREAK_NOT_FOUND — the user hasn't qualified for this streak yet (no state exists to grant against).

Curl:

curl -X POST '${BASE_URL}/admin/projects/{projectId}/users/{userId}/streaks/{streakDefinitionId}/grant-shield' \
  -H 'Authorization: Bearer ${DEV_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{ "count": 1 }'