Amba

Achievements

Achievement definitions with XP rewards, unlock criteria, and optional hidden state.

Achievements unlock automatically based on the evaluation of their criteria JSONB. Read the shared CreateAchievementInput type for the full schema.

Most of this surface manages achievement definitions. The two per-user endpoints (/grant, /revoke) are the support / moderation path — manually award or claw back an achievement for a specific user when the automatic criteria evaluation isn't the right tool.

Endpoints

MethodPathDescription
POST/admin/projects/:projectId/achievementsCreate an achievement.
GET/admin/projects/:projectId/achievementsList achievements, ordered by sort_order.
GET/admin/projects/:projectId/achievements/:achievementIdFetch a single achievement.
PATCH/admin/projects/:projectId/achievements/:achievementIdPartial update.
DELETE/admin/projects/:projectId/achievements/:achievementIdDelete.
POST/admin/projects/:projectId/achievements/:achievementId/grantManually unlock an achievement for a user.
POST/admin/projects/:projectId/achievements/:achievementId/revokeClaw back a user's unlock (inverse of grant).

POST /admin/projects/:projectId/achievements

Request

FieldTypeRequiredDefault
keystringyes
namestringyes
descriptionstringnonull
icon_urlstringnonull
xp_rewardnumberno0
criteriaobjectyes
is_hiddenbooleannofalse
sort_ordernumberno0

criteria is a JSONB rule tree — see CreateAchievementInput in @layers/amba-shared for the current shape (event-count thresholds, property filters, composite all/any combinators).

Response 201

{
  "data": {
    "id": "…",
    "key": "first_workout",
    "name": "First Workout",
    "xp_reward": 10,
    "criteria": {},
    "is_hidden": false,
    "sort_order": 0
  }
}

Errors

  • 500 CREATE_FAILED.

Try it:

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

Curl:

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

GET /admin/projects/:projectId/achievements

Ordered by sort_order.

{ "data": [{ "id": "…", "key": "first_workout", "name": "…", "xp_reward": 10 }] }

Try it:

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

Curl:

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

GET /admin/projects/:projectId/achievements/:achievementId

Errors

  • 404 NOT_FOUND.

Try it:

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

Curl:

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

PATCH /admin/projects/:projectId/achievements/:achievementId

Allowed fields: name, description, icon_url, xp_reward, criteria, is_hidden, sort_order, is_active.

Errors

  • 404 NOT_FOUND.
  • 500 UPDATE_FAILED.

Try it:

PATCH/admin/projects/%7B%7BprojectId%7D%7D/achievements/%7B%7BachievementId%7D%7D
developer auth
curl -X PATCH 'https://api.amba.dev/v1/admin/projects/%7B%7BprojectId%7D%7D/achievements/%7B%7BachievementId%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}/achievements/{achievementId}' \
  -H 'Authorization: Bearer ${DEV_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{}'

DELETE /admin/projects/:projectId/achievements/:achievementId

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

Try it:

DELETE/admin/projects/%7B%7BprojectId%7D%7D/achievements/%7B%7BachievementId%7D%7D
developer auth
curl -X DELETE 'https://api.amba.dev/v1/admin/projects/%7B%7BprojectId%7D%7D/achievements/%7B%7BachievementId%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}/achievements/{achievementId}' \
  -H 'Authorization: Bearer ${DEV_TOKEN}'

POST /admin/projects/:projectId/achievements/:achievementId/grant

Manually unlock an achievement for a specific user (marks it unlocked now). For support, promos, or corrections — the rest of the surface only defines the criteria the system evaluates automatically.

Idempotent: re-granting an already-unlocked achievement keeps the original unlocked_at (no clobber). A grant does not auto-award the achievement's xp_reward — that's reserved for a genuine, criteria-driven unlock. Award XP explicitly via /xp/grant if you want it.

Request (GrantAchievementInput)

FieldTypeRequiredDescription
app_user_iduuidyesUser to award the achievement to.

Response 201

{
  "data": {
    "app_user_id": "…",
    "achievement_id": "…",
    "unlocked_at": "…"
  }
}

Errors

  • 400 VALIDATION_ERRORapp_user_id missing.
  • 400 INVALID_IDachievementId or app_user_id isn't a UUID.
  • 404 NOT_FOUND — the achievement definition doesn't exist.
  • 500 GRANT_FAILED.

Try it:

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

Curl:

curl -X POST '${BASE_URL}/admin/projects/{projectId}/achievements/{achievementId}/grant' \
  -H 'Authorization: Bearer ${DEV_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{ "app_user_id": "…" }'

POST /admin/projects/:projectId/achievements/:achievementId/revoke

The inverse of grant: remove a user's unlock entirely.

Request (GrantAchievementInput)

FieldTypeRequiredDescription
app_user_iduuidyesUser to revoke the achievement from.

Response 200

{
  "data": {
    "revoked": true,
    "achievement": {
      "app_user_id": "…",
      "achievement_id": "…",
      "unlocked_at": "…"
    }
  }
}

Errors

  • 400 VALIDATION_ERRORapp_user_id missing.
  • 400 INVALID_IDachievementId or app_user_id isn't a UUID.
  • 404 USER_ACHIEVEMENT_NOT_FOUND — the user doesn't currently hold this achievement.
  • 500 REVOKE_FAILED.

Try it:

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

Curl:

curl -X POST '${BASE_URL}/admin/projects/{projectId}/achievements/{achievementId}/revoke' \
  -H 'Authorization: Bearer ${DEV_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{ "app_user_id": "…" }'