Use these endpoints to show who a key acts as, which communities it can manage, and to keep an account profile in sync with another system. You can read and edit your own profile, or the profile of a community you manage.
Some field names still say person and community. In the API both identify accounts: a "community" is an account that other accounts join. IDs of either kind are account IDs.
API access needs a Honey Bee plan or above; see the developer overview. Errors, scope failures and rate limits follow Requests, errors and limits. Account routes share the 600 requests per minute budget listed under rate limits, and JSON bodies are limited to 128 KiB (413 invalid_request when larger).
The rest of the account family is split over these pages:
- Account settings and profile builders: account state, preferences, linked communities, overview, widgets and welcome page.
- Wallets and NFT exposure.
- Data export, deletion and key revocation.
- Uploads: get upload IDs for profile images.
Each endpoint shows curl. Endpoints with a request body, and the identity and profile reads, also show JavaScript and Python; the other endpoints follow the same pattern with the same headers.
#Identity
#Who is the key acting as
/api/v1/meScopeaccount:readReturns the account behind the key, the key's scopes, and the accounts you can manage with it. credential.communityIds is present only when the key is limited to specific accounts. person.handle is omitted when the account has no handle.
curl https://app.hive3.tech/api/v1/me \
-H "Authorization: Bearer $HIVE_API_KEY"const res = await fetch("https://app.hive3.tech/api/v1/me", {
headers: { Authorization: `Bearer ${process.env.HIVE_API_KEY}` },
});
const { data } = await res.json();import os, requests
res = requests.get(
"https://app.hive3.tech/api/v1/me",
headers={"Authorization": "Bearer " + os.environ["HIVE_API_KEY"]},
)
data = res.json()["data"]Returns 200.
{
"data": {
"person": { "id": "account_123", "displayName": "Ada Lovelace", "handle": "ada" },
"credential": {
"id": "key_123",
"scopes": ["account:read", "communities:read"],
"communityIds": ["account_456"]
},
"communities": [
{
"communityId": "account_456",
"name": "Design Guild",
"role": "admin",
"capabilities": { "canRead": true, "canWrite": true, "canModerate": true }
}
]
}
}#List managed accounts and capabilities
/api/v1/capabilitiesScopecommunities:readReturns the same body as GET /api/v1/me. Use it from tools that only hold community scopes. role is owner, admin, moderator or member, and the capabilities reflect the key owner's current role, not the role at the time the key was created.
curl https://app.hive3.tech/api/v1/capabilities \
-H "Authorization: Bearer $HIVE_API_KEY"#Profile
Profile reads and writes act on the key owner's account. Add ?account= to act on a managed account; see Managed accounts.
#Get a profile
/api/v1/profileScopeaccount:readReturns the profile, including access type, plan and deletion state. primaryEmail is returned only for your own account; for a managed account it is null. The deletion timestamps and updatedAt are Unix milliseconds. Image and attachment URLs are resolved from the uploads attached to the profile.
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
account | query | string | No | Account ID or handle of a managed account. Defaults to your own account. |
curl https://app.hive3.tech/api/v1/profile \
-H "Authorization: Bearer $HIVE_API_KEY"const res = await fetch("https://app.hive3.tech/api/v1/profile", {
headers: { Authorization: `Bearer ${process.env.HIVE_API_KEY}` },
});
const { data } = await res.json();import os, requests
res = requests.get(
"https://app.hive3.tech/api/v1/profile",
headers={"Authorization": "Bearer " + os.environ["HIVE_API_KEY"]},
)
data = res.json()["data"]Returns 200. name and displayName are the same value, as are handle and username.
{
"data": {
"id": "account_123",
"handle": "ada",
"username": "ada",
"name": "Ada Lovelace",
"displayName": "Ada Lovelace",
"primaryEmail": "ada@example.com",
"title": "Engineer",
"experience": "",
"shortDescription": "Notes on analytical engines.",
"description": "",
"location": "London",
"badges": [],
"socials": [{ "socialType": "x", "address": "https://x.com/ada" }],
"image": "https://example.com/avatar.png",
"imageStorageId": "upload_123",
"heroImage": "",
"heroImageStorageId": null,
"attachmentUrl": "",
"attachmentStorageId": null,
"showCollaboratorCount": true,
"customCollaboratorCount": null,
"accessType": "open",
"membershipTier": "honey",
"accountStatus": "active",
"accountDeletionRequestedAt": null,
"accountDeletionScheduledAt": null,
"accountDeletionCancelledAt": null,
"publicNftExposure": false,
"updatedAt": 1793000000000
}
}404 not_found: theaccountvalue matches no account.
#Update a profile
/api/v1/profileScopeaccount:writeUpdates only the fields you send and returns the full profile in the same shape as the read above. A field with the wrong type is ignored, not rejected. For string fields, null clears the value. Limited to 60 requests per minute.
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
account | query | string | No | Managed account ID or handle. |
name | body | string or null | No | Display name. Alias displayName. null resets it to the handle. |
username | body | string | No | Handle. Alias handle. Lowercased, a leading @ is removed, 3 to 30 characters of a-z, 0-9, _ and -, starting with a letter or number. Reserved or taken handles return 409 conflict. null leaves it unchanged. |
title, experience, shortDescription, description, location | body | string or null | No | Plain text. |
badges | body | string[] or null | No | Replaces the list. |
socials | body | object[] or null | No | Replaces the list. Each item is { "socialType": "x", "address": "https://x.com/ada" }; items missing either field are dropped. |
showCollaboratorCount | body | boolean | No | Show the member count on the profile. |
customCollaboratorCount | body | number or null | No | Overrides the displayed member count; null removes the override. |
image | body | string or null | No | Profile image URL. Alias profileImage. |
imageStorageId | body | string or null | No | Upload ID of an image from Uploads. Alias profileImageStorageId. Wins over image. An empty string or null clears it. |
heroImage, heroImageStorageId | body | string or null | No | Banner image URL or upload ID. Aliases bannerImage, bannerImageStorageId. |
attachmentUrl, attachmentStorageId | body | string or null | No | Attached file: URL or upload ID of an image or document. |
curl -X PATCH https://app.hive3.tech/api/v1/profile \
-H "Authorization: Bearer $HIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"Engineer","location":"London","imageStorageId":"upload_123"}'const res = await fetch("https://app.hive3.tech/api/v1/profile", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.HIVE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ title: "Engineer", location: "London", imageStorageId: "upload_123" }),
});
const { data } = await res.json();import os, requests
res = requests.patch(
"https://app.hive3.tech/api/v1/profile",
headers={"Authorization": "Bearer " + os.environ["HIVE_API_KEY"]},
json={"title": "Engineer", "location": "London", "imageStorageId": "upload_123"},
)
data = res.json()["data"]Returns 200 with the updated profile. Notable errors:
400 invalid_request: malformed JSON, or an upload ID that is not a valid ID or whose stored file is not allowed for that field (images only forimageStorageIdandheroImageStorageId).404 not_found: an upload ID that does not exist or was uploaded by another account.409 conflict: the handle is reserved or already taken (Handle is not available,Handle is reserved).
#Check a handle
/api/v1/profile/handleScopeaccount:readChecks whether a handle can be assigned to the account, using the same rules as PATCH /api/v1/profile. The handle the account already has counts as available.
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
handle | query | string | Yes | Handle to check. Normalized before checking; the normalized value is returned. |
account | query | string | No | Managed account ID or handle. |
curl "https://app.hive3.tech/api/v1/profile/handle?handle=ada" \
-H "Authorization: Bearer $HIVE_API_KEY"Returns 200. When the handle is unavailable, message says why.
{ "data": { "available": false, "handle": "ada", "message": "Handle is not available" } }400 invalid_request:handleis missing.
#Change profile access
/api/v1/profile/accessScopeaccount:writeSets who can join the account. Anything other than open needs the target account to be on Honey Bee or above. Switching private to open accepts every pending application; switching private to open-subscription discards them. Limited to 30 requests per minute.
| Name | In | Type | Required | Notes |
|---|---|---|---|---|
account | query | string | No | Managed account ID or handle. |
accessType | body | string | Yes | open, private, open-subscription or private-subscription. The older names public, protected, open_paywall and private_paywall are accepted. |
subscriptionId | body | string | For subscription types | One of the account's own subscription plans. Moderators can only choose a plan the account owns. |
curl -X PATCH "https://app.hive3.tech/api/v1/profile/access?account=account_456" \
-H "Authorization: Bearer $HIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"accessType":"private"}'const res = await fetch("https://app.hive3.tech/api/v1/profile/access?account=account_456", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.HIVE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ accessType: "private" }),
});
const { data } = await res.json();import os, requests
res = requests.patch(
"https://app.hive3.tech/api/v1/profile/access",
params={"account": "account_456"},
headers={"Authorization": "Bearer " + os.environ["HIVE_API_KEY"]},
json={"accessType": "private"},
)
data = res.json()["data"]Returns 200.
{ "data": { "id": "account_456", "accessType": "private" } }400 invalid_request: unknownaccessType, orsubscriptionIdmissing for a subscription type.403 forbidden: the target account is below Honey Bee (Honey Bee membership is required for non-open account access), or the plan is not one of the account's own.
#Managed accounts
The profile routes on this page (/profile, /profile/handle, /profile/access) and the builder routes in Account settings and profile builders accept an optional account query parameter holding an account ID or handle.
- Omit it, or pass your own account, and the route behaves as described above.
- For another account, reads also need the
communities:readscope and writes needcommunities:write. A missing scope returns403 insufficient_scopewithrequiredScopes. - If the key is limited to specific accounts, the account must be on its list:
403 forbidden,API key does not include this managed account. - You must currently be an owner, admin or moderator of the account:
403 forbidden,Only account owners, admins and moderators can manage this account. - An unknown account returns
404 not_found. - Uploads always belong to the key owner. You can attach your own uploads to a managed profile; an upload ID from another account returns
404 not_found.
See Authentication and API keys for how keys and managed accounts relate.