Skip to content
Developers

Credentials

Read the credentials an account issues, award custom credentials to people by handle, and list the credentials the key owner holds or can claim.

Use the credential endpoints to award a custom credential from your own systems, for example when someone finishes a program you track elsewhere, and to show which credentials an account issues, which ones a person holds and which are waiting to be claimed. Creating, editing, minting and deploying credentials, and claiming one, stay in the Hive3 app: an award notifies the person, who then claims the credential there.

JavaScript and Python follow the same request pattern as the tabbed examples; the cards that show only curl are trivial to translate.

#Scopes, plan and targeting

ScopeAllows
credentials:readRead credentials an account issues, the key owner's claims, and credentials awarded to the key owner.
credentials:writeAward custom credentials to people.

No other scope implies these; keys created before they existed need to be replaced (scopes). API access needs Honey Bee or above (overview).

The list route acts on the key owner's own account unless you add ?account=<account ID or @handle>. The API calls an account that others join a community, so for another account the key also needs communities:read (reads) or communities:write (writes), must include that account when the key is limited to selected accounts, and the key owner must currently be an owner, admin or moderator of it. Routes that take a credential ID use the account that owns the credential and ignore ?account=. See managed accounts.

POST /api/v1/credentials/{credentialId}/awards is limited per awarding account to 30 requests per minute and 500 people per day. The budget is shared with the Hive3 app and counts every handle you send, including people who already hold the award. It sits on top of the account-wide budget (rate limits). Over a limit returns 429 rate_limited with a Retry-After header.

#The credential object

FieldTypeNotes
id, accountIdstringCredential ID and the account that issues it.
name, description, imageUrlstringDisplay details.
attachmentTypestringgeneral for a custom credential, or event, course, quest, coordination (a booking) or proof_of_human for credentials earned another way. Only general credentials can be awarded.
attachmentIdstring or nullThe event, course, quest or booking the credential belongs to, or null.
claimAccessstringopen (anyone can claim it) or awarded (only people who were awarded it can claim it).
maxSupplystring or nullWhole-number cap on claims, or null for no cap.
deployStatusstringnot_deployed, scheduled, pending, confirmed or failed.
chainNamestringThe network the credential is issued on, for example Base.
createdAt, updatedAtstringISO 8601 timestamps (timestamps).

#Read credentials an account issues

GET/api/v1/credentialsScopecredentials:read

Lists the credentials owned by the account, newest first.

NameInTypeRequiredNotes
accountquerystringNoAccount ID or @handle. Defaults to the key owner.
limitqueryintegerNo1 to 100, default 25.
cursorquerystringNoOpaque; page.nextCursor from the previous page (pagination).
bash
curl "https://app.hive3.tech/api/v1/credentials?account=@design-guild" \
  -H "Authorization: Bearer $HIVE_API_KEY"

Returns 200.

json
{
  "data": [{
    "id": "credential_123", "accountId": "account_123", "name": "Mentor", "description": "Helped five members ship", "imageUrl": "https://example.com/mentor.png",
    "attachmentType": "general", "attachmentId": null, "claimAccess": "awarded", "maxSupply": null, "deployStatus": "confirmed", "chainName": "Base",
    "createdAt": "2026-10-27T18:00:00.000Z", "updatedAt": "2026-10-27T18:00:00.000Z"
  }],
  "page": { "nextCursor": null, "hasMore": false }
}

Errors: 403 insufficient_scope (missing credentials:read, or communities:read for another account), 403 forbidden (not in the key's allowlist, or your role does not allow it), 404 not_found (account not found).

GET/api/v1/credentials/{credentialId}Scopecredentials:read

Returns one credential. You can read a credential you manage, or one whose issuing account's activity is visible to you; otherwise the response is 404 not_found (Credential not found). mine and claimable are reserved and never credential IDs.

bash
curl https://app.hive3.tech/api/v1/credentials/credential_123 \
  -H "Authorization: Bearer $HIVE_API_KEY"

Returns 200 with the credential object shown above.

#Award a credential

POST/api/v1/credentials/{credentialId}/awardsScopecredentials:write

Awards a custom (general) credential to the accounts with the given handles. Each person who is newly awarded gets a notification and can claim the credential in the app. Event, course, quest, booking and proof of human credentials are earned, not awarded, and return 400.

Handles are matched without case and with or without the leading @; @Ada, ada and ada are the same handle, and duplicates and blank entries are ignored. Someone who already holds the award is skipped: they are not counted in awarded and are not notified again, so repeating a request after a timeout is safe. Handles that match no active account are returned in notFound, in lower case without the @. Accounts that are private, still being set up, scheduled for deletion or deleted are reported in notFound exactly like unknown handles, so the response never shows whether such an account exists.

NameInTypeRequiredNotes
handlesbodyarray of stringsYes1 to 50 handles. The body can be up to 16 KiB.
bash
curl -X POST https://app.hive3.tech/api/v1/credentials/credential_123/awards \
  -H "Authorization: Bearer $HIVE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"handles":["@ada","grace","nobody"]}'

Returns 200 (an award is not a new resource, so there is no 201). Here ada and grace were newly awarded and nobody matched no account.

json
{ "data": { "awarded": 2, "notFound": ["nobody"] } }
StatuscodeWhen
400invalid_requesthandles is not an array of strings (handles must be an array of account handles), is empty or lists more than 50 people (handles must list 1-50 people), or the credential is not custom (Only custom credentials can be awarded.).
403forbiddenYou may not manage this credential (You don't have permission to manage this credential), your role does not allow it, or the account is not in the key's allowlist.
403insufficient_scopeThe key lacks credentials:write, or communities:write for a credential owned by another account.
404not_foundCredential not found.
429rate_limitedMore than 30 award requests in a minute, or more than 500 people in a day. Wait for Retry-After seconds.

#Read your own credentials

GET/api/v1/credentials/mineScopecredentials:read

Lists the key owner's credential claims, newest first. status is pending, confirmed or failed. It always shows the key owner's own claims and ignores ?account=.

NameInTypeRequiredNotes
limitqueryintegerNo1 to 100, default 25.
cursorquerystringNoOpaque; from the previous page.
bash
curl "https://app.hive3.tech/api/v1/credentials/mine" \
  -H "Authorization: Bearer $HIVE_API_KEY"

Returns 200. credential is the credential object shown above.

json
{
  "data": [{
    "id": "claim_123", "credentialId": "credential_123", "status": "confirmed", "chainName": "Base", "claimedAt": "2026-10-28T09:00:00.000Z",
    "credential": { "id": "credential_123", "accountId": "account_123", "name": "Mentor", "description": "Helped five members ship", "imageUrl": "https://example.com/mentor.png", "attachmentType": "general", "attachmentId": null, "claimAccess": "awarded", "maxSupply": null, "deployStatus": "confirmed", "chainName": "Base", "createdAt": "2026-10-27T18:00:00.000Z", "updatedAt": "2026-10-27T18:00:00.000Z" }
  }],
  "page": { "nextCursor": null, "hasMore": false }
}
GET/api/v1/credentials/claimableScopecredentials:read

Lists credentials that were awarded to the key owner and are not claimed yet: the credential object plus awardedAt. Claiming happens in the app. It ignores ?account= and takes the same limit and cursor as mine.

bash
curl "https://app.hive3.tech/api/v1/credentials/claimable?limit=10" \
  -H "Authorization: Bearer $HIVE_API_KEY"

Returns 200.

json
{
  "data": [{
    "id": "credential_123", "accountId": "account_123", "name": "Mentor", "description": "Helped five members ship", "imageUrl": "https://example.com/mentor.png",
    "attachmentType": "general", "attachmentId": null, "claimAccess": "awarded", "maxSupply": null, "deployStatus": "confirmed", "chainName": "Base",
    "createdAt": "2026-10-27T18:00:00.000Z", "updatedAt": "2026-10-27T18:00:00.000Z", "awardedAt": "2026-10-27T18:30:00.000Z"
  }],
  "page": { "nextCursor": null, "hasMore": false }
}

#Award a credential end to end

  1. Find the credential

    Call GET /api/v1/credentials (add ?account= for a community you help run) and pick a credential whose attachmentType is general. Keep its id.

  2. Award it

    Call POST /api/v1/credentials/{credentialId}/awards with up to 50 handles. Keep the response's notFound list.

  3. Handle misses and retries

    Fix or drop the handles in notFound and send only those again. Sending the full list again is safe: people who already hold the award are skipped and not notified twice.

  4. Confirm with the recipient

    When the recipient's own key calls GET /api/v1/credentials/claimable, the credential is listed until they claim it in the app. After that it appears in GET /api/v1/credentials/mine.