REST API
Every endpoint of the public Guild API.
The Guild REST API lets your own code read a guild's roles and members, check a user's memberships, and grant or deduct points. Use it for integrations that run without a person in the loop: a game server that awards points, a bot that checks whether someone holds a role, a dashboard of members.
REST API or an agent
If you want to manage a guild by asking in plain language, or let an AI agent set up roles, requirements and rewards, use the Guild MCP server instead. It's free on every plan and can do much more than the REST API's endpoints. The REST API is for programs you write yourself, calling a fixed set of endpoints.
Get an API key
API keys belong to a guild.
- In the admin panel, open Agents.
- At the bottom of the page, open For developers.
- Press Create key, give it a Key name, and optionally limit it to the endpoints it needs.
- Copy the key. It's shown in full only once.
Send the key as a Bearer token in the Authorization header. Keep it secret: anyone with the key can call the API as your guild.
API keys need the Pro plan or above. Growth and Enterprise get higher rate limits. See Plans.
Interactive reference
The live, interactive reference, where you can try requests, is at https://api.guild.xyz/docs. The endpoints are also listed below.
Verified person (staff)
The review queue
GET https://api.guild.xyz/admin/person-verification/queue
Superadmins only. Oldest first. status is PENDING, IN_REVIEW, NEEDS_INFO or DECIDED.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
status (optional) |
query | Tab. Default PENDING. string |
cursor (optional) |
query | From nextCursor. string |
limit (optional) |
query | 1 to 100. Default 50. integer (int64) |
Returns 200: A page. (QueuePageBody)
| Field | Type | Description |
|---|---|---|
items |
object[] | QueueItem[]. |
nextCursor (optional) |
string |
401Signed out.403Not staff.422Validation failed.
A request with the reviewer signals
GET https://api.guild.xyz/admin/person-verification/requests/{requestId}
Superadmins only. refresh=1 recomputes the signals, at most once every 10 minutes (a newer stored report is returned instead).
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
requestId |
path | Request id (UUID). string |
refresh (optional) |
query | 0 or 1. string |
Returns 200: The detail. (RequestDetailBody)
| Field | Type | Description |
|---|---|---|
audit |
object[] | |
history |
object[] | |
member |
object | |
request |
object | |
signals (optional) |
object or SignalReport | |
signalsComputedAt (optional) |
string |
401Signed out.403Not staff, orSELF_REVIEW.404No such request.
Claim a request
POST https://api.guild.xyz/admin/person-verification/requests/{requestId}/claim
Sets IN_REVIEW with a 30-minute soft lock. Another reviewer's live claim gives 409 CLAIMED with claimedBy and claimedUntil.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
requestId |
path | Request id (UUID). string |
Returns 200: The request. (object)
401Signed out.403Not staff, orSELF_REVIEW.404No such request.409CLAIMEDorNOT_CLAIMABLE.
Decide a request
POST https://api.guild.xyz/admin/person-verification/requests/{requestId}/decision
APPROVED grants the badge for 365 days and pushes it to the protocol. staffNote is required (1 to 2000 characters); NEEDS_INFO also requires memberMessage. Every outcome writes an audit row and notifies the member.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
requestId |
path | Request id (UUID). string |
Body (DecisionBody):
| Field | Type | Description |
|---|---|---|
memberMessage (optional) |
string | Shown to the member. At most 500 characters (1000 for NEEDS_INFO, where it is required). |
outcome |
string | APPROVED, REJECTED or NEEDS_INFO. |
reasonCategory (optional) |
string | |
staffNote |
string | 1 to 2000 characters. Staff only. |
Returns 200: The request. (object)
401Signed out.403Not staff, orSELF_REVIEW.404No such request.409CLAIMEDorNOT_OPEN.422Validation failed.
A member's badge, requests and audit
GET https://api.guild.xyz/admin/person-verification/users/{userId}
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
userId |
path | User id (UUID). string |
Returns 200: The member's verification. (UserVerificationBody)
| Field | Type | Description |
|---|---|---|
audit |
object[] | |
badge (optional) |
object | |
requests |
object[] |
401Signed out.403Not staff.
Grant a badge
POST https://api.guild.xyz/admin/person-verification/users/{userId}/grant
For staff cases. Writes a GRANTED audit row and pushes the badge.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
userId |
path | User id (UUID). string |
Body (GrantBody):
| Field | Type | Description |
|---|---|---|
note |
string | |
validUntil (optional) |
string | Defaults to one year from now. |
Returns 200: The badge. (object)
401Signed out.403Not staff, orSELF_REVIEW.422Validation failed.
Revoke a badge
POST https://api.guild.xyz/admin/person-verification/users/{userId}/revoke
Pushes verified = false (the protocol then removes the roles and rewards it gated) and notifies the member.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
userId |
path | User id (UUID). string |
Body (RevokeBody):
| Field | Type | Description |
|---|---|---|
reason |
string | |
reasonCategory (optional) |
string |
Returns 200: The badge. (object)
401Signed out.403Not staff, orSELF_REVIEW.404No active badge.422Validation failed.
Analytics
Search guild/user events
GET https://api.guild.xyz/analytics/events
Search the raw analytics event log. Provide userId to see one user's events (defaults to the caller; querying another user's userId without a guildId requires being a superAdmin), guildId to see one guild's events (requires being an admin, owner, or superAdmin of that guild), or both. SuperAdmins may omit both to query platform-wide; other callers default to their own userId when neither is given. roleId, requirementId, and rewardId further filter within a guildId search. hasMore indicates whether more rows exist beyond limit.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
userId (optional) |
query | Filter to one user. Defaults to the caller; another user's id requires guildId (with admin/owner/superAdmin access to it) or superAdmin. string (uuid) |
guildId (optional) |
query | Filter to one guild. Requires being an admin, owner, or superAdmin of it. string (uuid) |
roleId (optional) |
query | Filter to one role. Requires guildId. string (uuid) |
requirementId (optional) |
query | Filter to one requirement. Requires guildId. string (uuid) |
rewardId (optional) |
query | Filter to one reward. Requires guildId. string (uuid) |
startDate (optional) |
query | ISO 8601 range start. Defaults to 7 days before endDate. string |
endDate (optional) |
query | ISO 8601 range end. Defaults to now. string |
eventType (optional) |
query | Filter to one event type, e.g. join_guild. string |
limit (optional) |
query | Max rows to return, 1-10000. Defaults to 10000. integer (int64) |
Returns 200: Matching events. (AnalyticsGuildEventsResponse)
| Field | Type | Description |
|---|---|---|
events |
AnalyticsGuildEvent[] | |
hasMore |
boolean | true if more rows exist beyond limit. |
limit |
integer (int64) | The effective limit that was applied. |
400userIdorguildIdis required unless the caller is a superAdmin;guildIdis required when filtering byroleId,requirementId, orrewardId.401Not logged in.403userIdnames another user andguildIdis absent and the caller is not a superAdmin; orguildIdis present and the caller is not an admin, owner, or superAdmin of it.404No guild matches the requested guildId.422Request validation failed:userId/guildId/roleId/requirementId/rewardIdis not a UUID,startDate/endDate/eventTypeis not a string, orlimitis not a positive integer at most 10000.429Rate limit hit. See the Retry-After header.
Get a user's activity heatmap
GET https://api.guild.xyz/analytics/heatmap
Daily activity counts for a user between startDate and endDate (both default to the last 365 days — wider than the other analytics endpoints, which default to 7). Defaults to the authenticated user; pass userId to view another user's activity instead — requires being that user or a superAdmin. eventType is accepted for parity with /analytics/profile but is not currently applied to the query — every event type is counted.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
userId (optional) |
query | Whose activity to fetch. Defaults to the authenticated user; another user's id requires superAdmin. string (uuid) |
startDate (optional) |
query | ISO 8601 range start. Defaults to 365 days before endDate. string |
endDate (optional) |
query | ISO 8601 range end. Defaults to now. string |
eventType (optional) |
query | Accepted but currently has no effect on this endpoint's result. string |
Returns 200: Daily activity counts. (AnalyticsUserActivityHeatmapResponse)
| Field | Type | Description |
|---|---|---|
activities |
AnalyticsActivityHeatmapDay[] |
400NouserIdwas given and no user is authenticated.401Not logged in.403userIdnames another user and the caller is not a superAdmin.422Request validation failed:userIdis not a UUID, orstartDate/endDate/eventTypeis not a string.429Rate limit hit. See the Retry-After header.
Get a user's profile activity
GET https://api.guild.xyz/analytics/profile
Metadata-enriched event history for a user (each event's guild, role, requirement, and reward is resolved to a short display record where still available) between startDate and endDate (both default to the last 7 days). Defaults to the authenticated user; pass userId to view another user's activity instead — requires being that user or a superAdmin. Never fails on an upstream data error — falls back to an empty events list.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
userId (optional) |
query | Whose activity to fetch. Defaults to the authenticated user; another user's id requires superAdmin. string (uuid) |
startDate (optional) |
query | ISO 8601 range start. Defaults to 7 days before endDate. string |
endDate (optional) |
query | ISO 8601 range end. Defaults to now. string |
eventType (optional) |
query | Filter to one event type, e.g. join_guild. string |
Returns 200: The user's enriched event history. (AnalyticsUserProfileResponse)
| Field | Type | Description |
|---|---|---|
events |
AnalyticsProfileEvent[] |
400NouserIdwas given and no user is authenticated.401Not logged in.403userIdnames another user and the caller is not a superAdmin.422Request validation failed:userIdis not a UUID, orstartDate/endDate/eventTypeis not a string.429Rate limit hit. See the Retry-After header.
Search rewards across all guilds
GET https://api.guild.xyz/analytics/rewards
Search rewards platform-wide, filtered to a single type (required, for query performance) and to rewards created within the last days (default 90). Public endpoint; no authentication required.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
type |
query | Reward type filter. One of PERMISSION, DISCORD, POINTS, SECRET, NFT, TELEGRAM, FORM2, PIN, VOTING, PROFILE_ITEM. Required. string |
search (optional) |
query | Free-text search term. string |
tags (optional) |
query | Only rewards whose guild has one of these tags. string[] |
chain (optional) |
query | Only rewards on this chain (NFT/PIN rewards). string |
isVerified (optional) |
query | Only rewards belonging to verified guilds. boolean |
sortBy (optional) |
query | One of createdAt, updatedAt, claimCount, guildMemberCount. Defaults to createdAt. string |
sortOrder (optional) |
query | One of ASC, DESC. Defaults to DESC. string |
rewardIds (optional) |
query | Restrict the search to these reward ids. string[] |
limit (optional) |
query | 0-100. Defaults to 32. integer (int64) |
offset (optional) |
query | Defaults to 0. integer (int64) |
days (optional) |
query | Only rewards created within this many days. Must be positive; defaults to 90. integer (int64) |
Returns 200: Matching rewards. (AnalyticsRewardSearchResponse)
| Field | Type | Description |
|---|---|---|
pagination |
AnalyticsRewardSearchPagination | The pagination field of GET /analytics/rewards. |
rewards |
AnalyticsRewardSearchItem[] | |
total |
integer (int64) |
422Request validation failed:typeis missing or not a valid reward type,sortBy/sortOrderis not one of the allowed values,limitis outside 0-100,offsetis outside 0-10000000, ordaysis not a positive integer.429Rate limit hit. See the Retry-After header.
List trending guilds
GET https://api.guild.xyz/analytics/trending
Verified guilds ranked by join count over period. Public endpoint; no authentication required.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
period |
query | One of today, week, month. Required. string |
Returns 200: Trending guilds, most joins first. (AnalyticsTrendingGuild[])
422Request validation failed:periodis missing or not one oftoday,week,month.429Rate limit hit. See the Retry-After header.
Get guild activity heatmap
GET https://api.guild.xyz/analytics/{guildIdLike}/activity-heatmap
Guild activity event counts (joins, leaves, role/reward grants and losses, identity connects/disconnects, form submits, points grants/revokes) bucketed by day of week and hour of day, between startDate and endDate (both default to the last 7 days). Requires the guild's subscription to include the analytics feature.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id. string (uuid) |
startDate (optional) |
query | ISO 8601 range start. Defaults to 7 days before endDate. string |
endDate (optional) |
query | ISO 8601 range end. Defaults to now. string |
Returns 200: Activity heatmap buckets. (AnalyticsGuildActivityHeatmapResponse)
| Field | Type | Description |
|---|---|---|
activities |
AnalyticsGuildActivityHeatmapBucket[] |
401Not logged in.403Not a guild admin, owner, or superAdmin; or the guild's subscription lacks the "analytics" feature.404No guild matches guildIdLike.422Request validation failed:guildIdLikeis not a UUID, orstartDate/endDateis not a string.429Rate limit hit. See the Retry-After header.
Get guild activity summary
GET https://api.guild.xyz/analytics/{guildIdLike}/activity-summary
Event-type counts and total POINTS granted for the guild between startDate and endDate (both default to the last 7 days). Requires the guild's subscription to include the analytics feature.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id. string (uuid) |
startDate (optional) |
query | ISO 8601 range start. Defaults to 7 days before endDate. string |
endDate (optional) |
query | ISO 8601 range end. Defaults to now. string |
Returns 200: Activity summary. (AnalyticsGuildActivitySummaryResponse)
| Field | Type | Description |
|---|---|---|
pointsSum |
integer (int64) | Total POINTS granted (grant_points events) in range. |
summaries |
AnalyticsGuildActivitySummaryItem[] |
401Not logged in.403Not a guild admin, owner, or superAdmin; or the guild's subscription lacks the "analytics" feature.404No guild matches guildIdLike.422Request validation failed:guildIdLikeis not a UUID, orstartDate/endDateis not a string.429Rate limit hit. See the Retry-After header.
Get guild activity time series
GET https://api.guild.xyz/analytics/{guildIdLike}/activity-timeseries
Time series of total/joins/roles/rewards event counts, bucketed by interval (default minute) between startDate and endDate (both default to the last 7 days). Requires the guild's subscription to include the analytics feature.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id. string (uuid) |
interval (optional) |
query | One of minute, hour, day, week, month. Defaults to minute. string |
startDate (optional) |
query | ISO 8601 range start. Defaults to 7 days before endDate. string |
endDate (optional) |
query | ISO 8601 range end. Defaults to now. string |
Returns 200: Activity time series buckets. (AnalyticsGuildActivityTimeSeriesResponse)
| Field | Type | Description |
|---|---|---|
buckets |
AnalyticsGuildActivityTimeSeriesBucket[] |
401Not logged in.403Not a guild admin, owner, or superAdmin; or the guild's subscription lacks the "analytics" feature.404No guild matches guildIdLike.422Request validation failed:guildIdLikeis not a UUID,intervalis not one ofminute,hour,day,week,month, orstartDate/endDateis not a string.429Rate limit hit. See the Retry-After header.
Compare native guild campaigns
GET https://api.guild.xyz/analytics/{guildIdLike}/campaigns
Campaigns are the guild's pages and current role assignments. Returns exact distinct role earners, grant/loss events, browser visitors, current membership snapshots, daily activity and safely attributable reward claims. The range is inclusive start, exclusive end, defaults to 30 days and is bounded to 90 days. Missing membership snapshots and shared reward claims are null. Requires guild administrator permissions and the analytics feature.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild UUID or URL name. string |
startDate (optional) |
query | ISO 8601 range start. Defaults to 30 days before endDate. string |
endDate (optional) |
query | ISO 8601 exclusive range end. Defaults to the current minute. string |
Returns 200: Campaign measurements with source and freshness notes. (CampaignAnalyticsResponse)
| Field | Type | Description |
|---|---|---|
campaigns |
CampaignAnalytics[] | |
dataSource |
string | |
generatedAt |
string | |
guildId |
string | |
limits |
CampaignLimits | |
notes |
string[] | |
period |
CampaignPeriod |
401Not logged in.403Guild admin permissions or analytics subscription required.404Guild does not exist.422Invalid date range or campaign catalogue exceeds the bounded limits.429Rate limit hit.500Analytics unavailable; failed queries never become zero-valued measurements.
Get guild member count history
GET https://api.guild.xyz/analytics/{guildIdLike}/members
Time series of the guild's member count, bucketed by interval (default hour) between startDate and endDate (both default to the last 7 days). Requires the guild's subscription to include the analytics feature.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id. string (uuid) |
interval (optional) |
query | One of hour, day, week, month. Defaults to hour. string |
startDate (optional) |
query | ISO 8601 range start. Defaults to 7 days before endDate. string |
endDate (optional) |
query | ISO 8601 range end. Defaults to now. string |
Returns 200: The guild's member-count snapshots. (AnalyticsGuildMembersResponse)
| Field | Type | Description |
|---|---|---|
snapshots |
AnalyticsGuildMemberSnapshot[] |
401Not logged in.403Not a guild admin, owner, or superAdmin; or the guild's subscription lacks the "analytics" feature.404No guild matches guildIdLike.422Request validation failed:guildIdLikeis not a UUID,intervalis not one ofhour,day,week,month, orstartDate/endDateis not a string.429Rate limit hit. See the Retry-After header.
Get guild page view history
GET https://api.guild.xyz/analytics/{guildIdLike}/page-views
Time series of page visitors and active-member visitors, bucketed by interval (default hour) between startDate and endDate (both default to the last 7 days). Requires the guild's subscription to include the analytics feature.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id. string (uuid) |
interval (optional) |
query | One of hour, day, week, month. Defaults to hour. string |
startDate (optional) |
query | ISO 8601 range start. Defaults to 7 days before endDate. string |
endDate (optional) |
query | ISO 8601 range end. Defaults to now. string |
Returns 200: The guild's page-view snapshots. (AnalyticsGuildPageViewsResponse)
| Field | Type | Description |
|---|---|---|
snapshots |
AnalyticsGuildPageViewSnapshot[] |
401Not logged in.403Not a guild admin, owner, or superAdmin; or the guild's subscription lacks the "analytics" feature.404No guild matches guildIdLike.422Request validation failed:guildIdLikeis not a UUID,intervalis not one ofhour,day,week,month, orstartDate/endDateis not a string.429Rate limit hit. See the Retry-After header.
Get guild reward claim counts
GET https://api.guild.xyz/analytics/{guildIdLike}/reward-claims
Per-reward claim counts (get_reward events) and the number of unique claimers for the guild between startDate and endDate (both default to the last 7 days). Requires the guild's subscription to include the analytics feature.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id. string (uuid) |
startDate (optional) |
query | ISO 8601 range start. Defaults to 7 days before endDate. string |
endDate (optional) |
query | ISO 8601 range end. Defaults to now. string |
Returns 200: Reward claim counts. (AnalyticsGuildRewardClaimsResponse)
| Field | Type | Description |
|---|---|---|
rewards |
AnalyticsRewardClaimCount[] | |
uniqueClaimers |
integer (int64) |
401Not logged in.403Not a guild admin, owner, or superAdmin; or the guild's subscription lacks the "analytics" feature.404No guild matches guildIdLike.422Request validation failed:guildIdLikeis not a UUID, orstartDate/endDateis not a string.429Rate limit hit. See the Retry-After header.
Get guild role member count history
GET https://api.guild.xyz/analytics/{guildIdLike}/roles
Time series of member counts per role, bucketed by interval (default hour) between startDate and endDate (both default to the last 7 days). Requires the guild's subscription to include the analytics feature.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id. string (uuid) |
roleIds (optional) |
query | Role ids to include, as a comma-separated list or a JSON array. Omit (or send empty) for every role. string[] |
interval (optional) |
query | One of hour, day, week, month. Defaults to hour. string |
startDate (optional) |
query | ISO 8601 range start. Defaults to 7 days before endDate. string |
endDate (optional) |
query | ISO 8601 range end. Defaults to now. string |
Returns 200: Per-role member-count snapshots. (AnalyticsGuildRolesResponse)
| Field | Type | Description |
|---|---|---|
roles |
AnalyticsGuildRoleSnapshot[] |
401Not logged in.403Not a guild admin, owner, or superAdmin; or the guild's subscription lacks the "analytics" feature.404No guild matches guildIdLike.422Request validation failed:guildIdLikeis not a UUID,roleIdsis neither a string nor an array,intervalis not one ofhour,day,week,month, orstartDate/endDateis not a string.429Rate limit hit. See the Retry-After header.
Chains
List all chains
GET https://api.guild.xyz/chains
Returns the fixed list of chains the Guild backend supports, including RPC URLs, contracts, and integration support flags for each. Static data — no database access — always the same 63 chains in the same order. Kept for legacy callers such as the billing service; internal Guild services should prefer the shared chains constant over calling this endpoint.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
Returns 200: Every supported chain. (ChainResponse[])
429Rate limit hit — only reachable when the caller has an active Guild session, since this route has no per-route auth. See the Retry-After header.
Get a chain by id
GET https://api.guild.xyz/chains/{id}
Looks up a single chain from the same static list as GET /chains, by its string id — not its numeric chainId.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
id |
path | The chain's string id, e.g. "ETHEREUM" or "POLYGON" — not the numeric chainId. string |
Returns 200: The matching chain. (ChainResponse)
| Field | Type | Description |
|---|---|---|
alchemyApiBaseUrl (optional) |
string | |
blockExplorer |
ChainBlockExplorer | A block explorer entry (Chain["blockExplorer"]). |
chainId |
integer (int64) | |
coingeckoId (optional) |
string | |
contracts |
ChainContracts | Chain["contracts"]. |
id |
string | The chain's string id, e.g. "ETHEREUM" or "POLYGON" — this is what GET /chains/{id} looks up by, not chainId. |
image |
string | |
integrations (optional) |
object or ChainIntegrations | |
name |
string | |
nativeCurrency |
ChainNativeCurrency | A chain's native gas currency (Chain["nativeCurrency"]). |
openseaItemBaseUrl (optional) |
string | |
privateRpcUrl (optional) |
string | Present only for chains with a dedicated private RPC endpoint. |
rpcNodes (optional) |
ChainRpcNode[] | Additive alongside rpcUrls. Omitted when the chain has no ether-proxy RPC overrides. |
rpcUrls |
string[] | Always non-empty. |
testnet |
boolean |
404No chain matches id. Body:{ "message": "Chain not found" }.429Rate limit hit — only reachable when the caller has an active Guild session, since this route has no per-route auth. See the Retry-After header.
Compliance
Delete a user's backend-owned data
DELETE https://api.guild.xyz/compliance/users/{userId}
Permanently deletes the user's backend-owned data — guild memberships, role progress, reward claims, point transactions, form submissions, and the user record itself — while retaining an audit log entry and billing records. Restricted to Guild's own internal privileged callers and superadmins; not a partner-integration endpoint.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
userId |
path | Backend id of the user whose data will be permanently deleted. string (uuid) |
Returns 200: Compliance delete completed. (ComplianceDeleteResponse)
| Field | Type | Description |
|---|---|---|
deleted |
boolean | Always true. |
guildIds |
string (uuid)[] | Ids of the guilds the user had a membership in (not guilds they owned — owning any guild blocks the delete with a 409). Each guild's membership row, and the guild/role member counts, were removed as part of this delete. |
retainedRecords |
string[] | Always ["audit_log", "billing"] — the categories of data that are deliberately retained rather than deleted. |
userId |
string (uuid) | The deleted user's backend id. |
401Not logged in, or the Guild session token is invalid or expired.403Logged in, but the caller is neither a superadmin nor an internal privileged caller.404No user with this id.409The user still owns one or more guilds. Transfer or delete those guilds first.422userId is not a valid UUID.429Rate limit hit. See the Retry-After header.
Crm
Search guild members
GET https://api.guild.xyz/crm/{guildIdLike}
Search and filter a guild's members for the CRM view. campaignId selects current members with ANY native campaign role and cannot be combined with other filters. Campaign and role cohorts are bounded to 100,000 members and sorted by joinedAt then userId before pagination. roleIds and rewardIds are mutually-exclusive priority filters: a non-empty roleIds wins over everything else; else a non-empty rewardIds wins over search/locations; only when both are empty do search and locations apply. The total match count is reported in the X-Total-Items response header — see that header's own description for when it is exact vs. approximate vs. unknown.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
campaignId (optional) |
query | Native guild page ID. Includes members holding ANY page role. Exclusive with all other filters; at most 100,000 cohort members and 500 roles. Exact counts and stable joinedAt/userId pagination. string (uuid) |
search (optional) |
query | Free-text search across member identities (wallet address, username, email, etc.). Ignored when roleIds or rewardIds is set. string |
roleIds (optional) |
query | Filter to members holding ALL of these role IDs — the intersection, not the union (UUID; repeat the param for multiple). Role IDs that do not belong to this guild are dropped, and if none survive the result is empty. Takes priority over rewardIds and search. string[] |
rewardIds (optional) |
query | Filter to members who have claimed all of these reward IDs (UUID; repeat the param for multiple). Used only when roleIds is empty; takes priority over search. string[] |
locations (optional) |
query | Filter by 2-letter location code (repeat the param for multiple). Only applied when neither roleIds nor rewardIds is set. string[] |
sortBy (optional) |
query | Sort field. Only joinedAt is supported. Defaults to joinedAt. string |
sortOrder (optional) |
query | Sort direction, ASC or DESC (case-insensitive). Defaults to DESC. string |
limit (optional) |
query | Page size. Defaults to 16, max 16. integer (int64) |
offset (optional) |
query | Pagination offset. Defaults to 0, max 10000000. integer (int64) |
Returns 200: Matching guild members. (CrmMemberResult[])
401Not logged in.403Logged in, but not an admin of this guild.404No guild found forguildIdLike.422Request validation failed: an out-of-rangeguildIdLike, or an invalid query parameter.429Rate limit hit. See the Retry-After header.
Get the guild's activity feed
GET https://api.guild.xyz/crm/{guildIdLike}/activity
Get a chronological (newest-first) feed of activity across all of a guild's members: joins, leaves, role gains/losses, reward claims/revokes, points earned/deducted, identity connects/disconnects, and form submissions. Backed by ClickHouse analytics events; each event is enriched with the acting user's identity info under actor. Returns a 200 with an empty events array (not a 404) when nothing matches. Deliberately exempt from the global per-user rate limit — admin dashboards fire several concurrent chart requests — so this route never answers 429.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
limit (optional) |
query | Max events to return. Defaults to 25, max 50. integer (int64) |
cursor (optional) |
query | Opaque nextCursor from the previous response. Pass the same filters and returned startDate/endDate for later pages. string |
campaignId (optional) |
query | Native campaign page ID in this guild. Includes events with a role currently assigned to that page. string (uuid) |
eventType (optional) |
query | Recorded event type: join_guild, leave_guild, get_role, claim_role, lose_role, get_reward, lose_reward, connect_identity, disconnect_identity, submit_form, grant_points or revoke_points. string |
userId (optional) |
query | Only events for this member ID. string (uuid) |
startDate (optional) |
query | Inclusive ISO 8601 start. Defaults to seven days before endDate; maximum range 90 days. string |
endDate (optional) |
query | Only include events at or before this ISO 8601 timestamp. string |
Returns 200: The guild's activity feed. (MemberTimelineActivityResponse)
| Field | Type | Description |
|---|---|---|
endDate |
string | |
events |
MemberTimelineActivityEvent[] | Newest first. |
nextCursor (optional) |
string | Opaque cursor ordered by millisecond timestamp plus recording key. Null after the last page, determined with one extra matching recording. |
startDate |
string |
401Not logged in.403Logged in, but not an admin of this guild.404No guild found forguildIdLike.422Request validation failed: an out-of-rangeguildIdLike, or an invalid query parameter.
Queue a member export
POST https://api.guild.xyz/crm/{guildIdLike}/export/async
Queue an async CSV export of guild members matching the given filters (the same filters as GET /crm/{guildIdLike}, minus limit/offset — an export always covers the full matching set, not one page; a limit/offset sent here is ignored). Returns immediately with a job id; poll GET /crm/{guildIdLike}/export/status/{jobId} for progress and the eventual download URL.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
campaignId (optional) |
query | Native guild page ID. Includes members holding ANY page role. Exclusive with all other filters; at most 100,000 cohort members and 500 roles. Exact counts and stable joinedAt/userId pagination. string (uuid) |
search (optional) |
query | Search exports are not supported; non-empty search returns 422. Clear search before exporting. string |
roleIds (optional) |
query | Filter to members holding ALL of these role IDs — the intersection, not the union (UUID; repeat the param for multiple). All selected IDs must belong to this guild; invalid ownership fails the job. Takes priority over rewardIds. string[] |
rewardIds (optional) |
query | Filter to members who have claimed all of these reward IDs (UUID; repeat the param for multiple). Used only when roleIds is empty; takes priority over search. string[] |
locations (optional) |
query | Filter by 2-letter location code (repeat the param for multiple). Only applied when neither roleIds nor rewardIds is set. string[] |
sortBy (optional) |
query | Sort field. Only joinedAt is supported. Defaults to joinedAt. string |
sortOrder (optional) |
query | Sort direction, ASC or DESC (case-insensitive). Defaults to DESC. string |
Returns 202: Export job created and queued. (CrmExportJobCreated)
| Field | Type | Description |
|---|---|---|
jobId |
string (uuid) | |
status |
string | Always "pending". |
401Not logged in.403Logged in, but not an admin of this guild.404No guild found forguildIdLike.422Request validation failed: an out-of-rangeguildIdLike, or an invalid query parameter.429Rate limit hit. See the Retry-After header.
Cancel an export job
POST https://api.guild.xyz/crm/{guildIdLike}/export/cancel/{jobId}
Cancel a pending or processing member export job. Only the job's creator or a superadmin may cancel it. Cancelling an already-cancelled job is a no-op that still returns 200; a completed or failed job can no longer be cancelled and returns 400 instead.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
jobId |
path | Export job id. string (uuid) |
Returns 200: The job was already cancelled, or was just cancelled. (CrmExportCancelResult)
| Field | Type | Description |
|---|---|---|
message |
string | "Job already cancelled" if it was already cancelled, otherwise "Export cancelled successfully". |
status |
string | Always "cancelled". |
400The job already finished (completedorfailed) and can no longer be cancelled.401Not logged in.403Not an admin of this guild, or (if the job exists) neither the job's creator nor a superadmin.404No guild found forguildIdLike, or no export job found forjobId.422Request validation failed:jobIdis not a UUID, or an out-of-rangeguildIdLike.429Rate limit hit. See the Retry-After header.
Get export job status
GET https://api.guild.xyz/crm/{guildIdLike}/export/status/{jobId}
Get the status of a member export job. Only the job's creator or a superadmin may view it: the 403 response here can mean either that the caller isn't an admin of this guild, or (if the job exists) that the caller is neither the job's creator nor a superadmin. The stored query snapshot always shows limit: 0, offset: 0 since an export covers the full matching set.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
jobId |
path | Export job id. string (uuid) |
Returns 200: The export job. (CrmExportJob)
| Field | Type | Description |
|---|---|---|
createdAt |
integer (int64) | Epoch milliseconds. |
error (optional) |
string | Present when the job failed. |
fileUrl (optional) |
string | Present once the export has completed. |
guildId |
string (uuid) | |
id |
string (uuid) | |
progress |
integer (int64) | Completion percentage, 0-100 (round(processed / total * 100); forced to 100 when the job completes) — not a row count. |
query |
CrmExportJobQuery | The query snapshot stored on a [CrmExportJob] — always has limit: 0, offset: 0 because an export covers the full matching set, not one page. |
status |
CrmExportJobStatus | CrmExportJob.status. |
total |
integer (int64) | Total rows to process. 0 until the worker has counted the matching set. |
userId |
string (uuid) |
401Not logged in.403Not an admin of this guild, or (if the job exists) neither the job's creator nor a superadmin.404No guild found forguildIdLike, or no export job found forjobId.422Request validation failed:jobIdis not a UUID, or an out-of-rangeguildIdLike.429Rate limit hit. See the Retry-After header.
List recent exports
GET https://api.guild.xyz/crm/{guildIdLike}/exports/recent
List the guild's completed member-export files, most recent first, with each file's export-job record resolved. Returns an empty exports array rather than an error when the guild has no exports yet.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
Returns 200: Recent exports. (CrmExportsRecentResponse)
| Field | Type | Description |
|---|---|---|
exports |
CrmRecentExport[] |
401Not logged in.403Logged in, but not an admin of this guild.404No guild found forguildIdLike.422Request validation failed: an out-of-rangeguildIdLike.429Rate limit hit. See the Retry-After header.
Get a member's activity timeline
GET https://api.guild.xyz/crm/{guildIdLike}/members/{userId}/timeline
Get a chronological (newest-first) timeline of one guild member's activity: guild joins, identity connects, role gains/losses, reward claims/revokes, points earned/deducted, and form submissions. Returns a 200 with an empty events array when the member has no recorded activity. 404 when userId is not a current member of the guild (the timeline exposes the member's connected accounts).
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
userId |
path | Guild member's user id. string (uuid) |
limit (optional) |
query | Max events to return. Defaults to 20, max 100. integer (int64) |
cursor (optional) |
query | ISO 8601 timestamp from a previous response's nextCursor; returns events strictly older than it. string |
Returns 200: The member's activity timeline. (MemberTimelineResponse)
| Field | Type | Description |
|---|---|---|
events |
MemberTimelineEvent[] | Newest first. |
nextCursor (optional) |
string | string | null — always emitted. An ISO 8601 timestamp to pass as the next page's cursor; null once fewer than limit events were returned (no further pages). |
401Not logged in.403Logged in, but not an admin of this guild.404No guild found forguildIdLike, oruserIdis not a current member of it.422Request validation failed:userIdis not a UUID, an out-of-rangeguildIdLike, or an invalid query parameter.429Rate limit hit. See the Retry-After header.
Boosts
Boosted guilds for Explore
GET https://api.guild.xyz/guild-boosts/boosted
Level 1 and up.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Resolve a vanity alias
GET https://api.guild.xyz/guild-vanity/{alias}
404 below level 3.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Public boost status of a guild
GET https://api.guild.xyz/guilds/{guildIdLike}/boosts
Optional session adds viewer. Cached 60 seconds.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Set or clear the animated banner
PUT https://api.guild.xyz/guilds/{guildIdLike}/boosts/animated-banner
Level 2. Guild admins only.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Recreate the Booster role
POST https://api.guild.xyz/guilds/{guildIdLike}/boosts/booster-role
Guild admins only.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Is this member boosting the guild
GET https://api.guild.xyz/guilds/{guildIdLike}/boosts/members/{userId}
Public. since is unix seconds.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Release the vanity alias
DELETE https://api.guild.xyz/guilds/{guildIdLike}/boosts/vanity
Guild admins only.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Claim a vanity alias
PUT https://api.guild.xyz/guilds/{guildIdLike}/boosts/vanity
Level 3. 409 VANITY_TAKEN.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
A guild's custom emoji
GET https://api.guild.xyz/guilds/{guildIdLike}/custom-emoji
Public.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Add a custom emoji
POST https://api.guild.xyz/guilds/{guildIdLike}/custom-emoji
Level 2. 409 EMOJI_LIMIT.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Archive a custom emoji
DELETE https://api.guild.xyz/guilds/{guildIdLike}/custom-emoji/{emojiId}
Guild admins only.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
The caller's boost slots
GET https://api.guild.xyz/me/boosts
MyBoosts.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Release a boost slot
DELETE https://api.guild.xyz/me/boosts/{slot}
The cooldown still applies to the next assignment.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Assign or move a boost
PUT https://api.guild.xyz/me/boosts/{slot}
403 PLUS_REQUIRED, 422 BOOST_SLOT_INVALID, 409 BOOST_COOLDOWN.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Restore a slot after resubscribing
POST https://api.guild.xyz/me/boosts/{slot}/restore
Ignores the cooldown.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (BoostJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Guilds
Search guilds
GET https://api.guild.xyz/guilds
Public guild search/listing with optional filters. Unlike GET /guilds/{guildIdLike}, results are always returned at admin-level detail — system-visibility rewards and non-public platforms are not filtered out here, regardless of the caller.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
limit (optional) |
query | Max results to return, 0-100. Defaults to 32. integer (int64) |
offset (optional) |
query | Pagination offset, 0-10000000. Defaults to 0. integer (int64) |
search (optional) |
query | Case-insensitive substring match against the guild's name or urlName. Must be empty or at least 3 characters. string |
platformUniqueId (optional) |
query | Filter to guilds with a connected platform whose id is <type>-<platformUniqueId> (the platform's uniqueId), e.g. a Discord server id. string |
owner (optional) |
query | Filter to guilds owned by this user id (UUID). string |
isVerified (optional) |
query | Filter by verification status. Accepts the literal query value "true" or "false". boolean |
tags (optional) |
query | Filter to guilds with any of these tags. Comma-separated, or repeat the query parameter. string |
sortBy (optional) |
query | One of memberCount, createdAt, updatedAt. Defaults to createdAt. string |
sortOrder (optional) |
query | One of ASC, DESC. Defaults to DESC. string |
Returns 200: Matching guilds. (GuildsGuild[])
422The query parameters failed validation (e.g. search is 1-2 characters, or limit/offset out of range).
Create a guild
POST https://api.guild.xyz/guilds
Create a guild owned by the logged-in user, along with a default "Home" page and "Member" role. If page/role creation fails, the guild is rolled back and deleted. urlName defaults to a slugified name when omitted.
Auth: your signed-in Guild session (x-guild-auth-token).
Body (GuildsCreateGuildRequest):
| Field | Type | Description |
|---|---|---|
contacts |
GuildsGuildContact[] | At least one contact is required. |
description (optional) |
string | Max 1500 characters. |
logoUrl (optional) |
string | |
name |
string | Non-empty after trimming. |
onboarding (optional) |
object or GuildsOnboarding | |
urlName (optional) |
string | Defaults to a slugified name when omitted. |
Returns 201: The newly created guild. (GuildsGuild)
| Field | Type | Description |
|---|---|---|
admins |
string[] | User ids. |
carousel (optional) |
object or GuildsGuildCarousel | |
color (optional) |
string | #rrggbb. |
contacts |
GuildsGuildContact[] | |
coverOpacity (optional) |
number (double) | 0-1. |
coverUrl (optional) |
string | |
createdAt |
string | ISO 8601. |
customization |
GuildsCustomization | customization — every field defaults to null. |
description (optional) |
string | Max 1500 characters. |
entry |
GuildsGuildEntry | The guild's entry gate (entry). |
featureFlags |
string[] | e.g. crm_with_socials, analytics, forms_v2, points_v2. |
guildPin (optional) |
object or GuildsGuildPin | |
id |
string (uuid) | |
isVerified |
boolean | |
legacyId (optional) |
integer (int64) | |
logoUrl (optional) |
string | |
mainPointsPlatformId (optional) |
string (uuid) | |
memberCount |
integer (int64) | |
name |
string | |
onboarding (optional) |
object or GuildsOnboarding | |
owner |
string (uuid) | |
pages |
GuildsGuildPageRef[] | |
permissions |
GuildsPermissions | permissions — nullable ids of the role/reward that grants read/write access, when the guild uses reward-gated permissions. |
platforms |
object[] | Connected platform configs (Discord, Telegram, POINTS, ...) — shape varies by type. Admins see every connected platform; other callers only platforms whose visibility is PUBLIC. |
rewards |
object[] | Reward configs — shape varies by type. Non-admin callers have system-visibility rewards (and NFT rewards not assigned to any role) filtered out. |
roleCount |
integer (int64) | |
socialLinks |
GuildsSocialLink[] | |
subscription (optional) |
object or GuildsGuildSubscription | |
tags |
string[] | |
updatedAt |
string | ISO 8601. |
urlName |
string |
400Malformed JSON in the request body.401Not logged in.409The (given or auto-derived) urlName is already taken by another guild.422Request body failed validation (e.g. missing name/contacts, or an empty contacts array).429Rate limit hit (600 requests/minute per user). See the Retry-After header.
Delete a guild
DELETE https://api.guild.xyz/guilds/{guildIdLike}
Delete a guild along with its roles, pages, rewards and platforms. Requires the current owner (or a superadmin). Any active Stripe subscription is cancelled on a best-effort basis — a Stripe failure is logged but does not block the delete.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id (UUID) or url name. string |
Returns 204: The guild was deleted.
401Not logged in.403The caller is not the guild owner (or a superadmin).404No guild with this id/url name.422guildIdLike failed validation (must be a UUID or a 1-50 character url name).429Rate limit hit (600 requests/minute per user). See the Retry-After header.
Get a guild
GET https://api.guild.xyz/guilds/{guildIdLike}
Get a guild by id or url name. Public — no authentication required. Callers below admin access get a filtered view: system-visibility rewards and non-PUBLIC platforms are omitted. Also mounted at GET /v2/guilds/{guildIdLike} as a legacy alias.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id (UUID) or url name. string |
Returns 200: The guild. (GuildsGuild)
| Field | Type | Description |
|---|---|---|
admins |
string[] | User ids. |
carousel (optional) |
object or GuildsGuildCarousel | |
color (optional) |
string | #rrggbb. |
contacts |
GuildsGuildContact[] | |
coverOpacity (optional) |
number (double) | 0-1. |
coverUrl (optional) |
string | |
createdAt |
string | ISO 8601. |
customization |
GuildsCustomization | customization — every field defaults to null. |
description (optional) |
string | Max 1500 characters. |
entry |
GuildsGuildEntry | The guild's entry gate (entry). |
featureFlags |
string[] | e.g. crm_with_socials, analytics, forms_v2, points_v2. |
guildPin (optional) |
object or GuildsGuildPin | |
id |
string (uuid) | |
isVerified |
boolean | |
legacyId (optional) |
integer (int64) | |
logoUrl (optional) |
string | |
mainPointsPlatformId (optional) |
string (uuid) | |
memberCount |
integer (int64) | |
name |
string | |
onboarding (optional) |
object or GuildsOnboarding | |
owner |
string (uuid) | |
pages |
GuildsGuildPageRef[] | |
permissions |
GuildsPermissions | permissions — nullable ids of the role/reward that grants read/write access, when the guild uses reward-gated permissions. |
platforms |
object[] | Connected platform configs (Discord, Telegram, POINTS, ...) — shape varies by type. Admins see every connected platform; other callers only platforms whose visibility is PUBLIC. |
rewards |
object[] | Reward configs — shape varies by type. Non-admin callers have system-visibility rewards (and NFT rewards not assigned to any role) filtered out. |
roleCount |
integer (int64) | |
socialLinks |
GuildsSocialLink[] | |
subscription (optional) |
object or GuildsGuildSubscription | |
tags |
string[] | |
updatedAt |
string | ISO 8601. |
urlName |
string |
404No guild with this id/url name.422guildIdLike failed validation (must be a UUID or a 1-50 character url name).
Update a guild
PUT https://api.guild.xyz/guilds/{guildIdLike}
Partially update a guild; only the fields present in the body are changed. Requires at least admin access. Changing isVerified, tags, featureFlags or subscription additionally requires superadmin rank; changing admins or owner additionally requires the current owner (or a superadmin).
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id (UUID) or url name. string |
Body (GuildsUpdateGuildRequest):
| Field | Type | Description |
|---|---|---|
admins (optional) |
string[] | User ids. Only the owner (or a superadmin) may change this. |
carousel (optional) |
object or GuildsGuildCarousel | |
color (optional) |
string | #rrggbb; nullable. |
contacts (optional) |
GuildsGuildContact[] | |
coverOpacity (optional) |
number (double) | 0-1; nullable. |
coverUrl (optional) |
string | |
customization (optional) |
object or GuildsCustomization | |
description (optional) |
string | Max 1500 characters; nullable. |
entry (optional) |
object or GuildsGuildEntry | |
featureFlags (optional) |
string[] | Superadmin only. |
guildPin (optional) |
object or GuildsGuildPin | |
isVerified (optional) |
boolean | Superadmin only. |
logoUrl (optional) |
string | |
mainPointsPlatformId (optional) |
string (uuid) | Must be null or the id of a POINTS platform belonging to this guild. |
name (optional) |
string | |
owner (optional) |
string (uuid) | User id of the new owner. Only the current owner (or a superadmin) may change this, and the target user must exist. |
pages (optional) |
GuildsGuildPageRef[] | |
socialLinks (optional) |
GuildsSocialLink[] | |
subscription (optional) |
object or GuildsGuildSubscription | |
tags (optional) |
string[] | |
urlName (optional) |
string |
Returns 200: The updated guild. (GuildsGuild)
| Field | Type | Description |
|---|---|---|
admins |
string[] | User ids. |
carousel (optional) |
object or GuildsGuildCarousel | |
color (optional) |
string | #rrggbb. |
contacts |
GuildsGuildContact[] | |
coverOpacity (optional) |
number (double) | 0-1. |
coverUrl (optional) |
string | |
createdAt |
string | ISO 8601. |
customization |
GuildsCustomization | customization — every field defaults to null. |
description (optional) |
string | Max 1500 characters. |
entry |
GuildsGuildEntry | The guild's entry gate (entry). |
featureFlags |
string[] | e.g. crm_with_socials, analytics, forms_v2, points_v2. |
guildPin (optional) |
object or GuildsGuildPin | |
id |
string (uuid) | |
isVerified |
boolean | |
legacyId (optional) |
integer (int64) | |
logoUrl (optional) |
string | |
mainPointsPlatformId (optional) |
string (uuid) | |
memberCount |
integer (int64) | |
name |
string | |
onboarding (optional) |
object or GuildsOnboarding | |
owner |
string (uuid) | |
pages |
GuildsGuildPageRef[] | |
permissions |
GuildsPermissions | permissions — nullable ids of the role/reward that grants read/write access, when the guild uses reward-gated permissions. |
platforms |
object[] | Connected platform configs (Discord, Telegram, POINTS, ...) — shape varies by type. Admins see every connected platform; other callers only platforms whose visibility is PUBLIC. |
rewards |
object[] | Reward configs — shape varies by type. Non-admin callers have system-visibility rewards (and NFT rewards not assigned to any role) filtered out. |
roleCount |
integer (int64) | |
socialLinks |
GuildsSocialLink[] | |
subscription (optional) |
object or GuildsGuildSubscription | |
tags |
string[] | |
updatedAt |
string | ISO 8601. |
urlName |
string |
400mainPointsPlatformId is not a POINTS platform of this guild, a gated entry is missing/has an invalid role, or nested rewards/platforms belong to a different guild.401Not logged in.403Below admin access for this guild; the update touches a superadmin-only or owner-only field without that rank; or an admin addition exceeds the guild's included seats.404Guild not found, or (when changing admins/owner) the referenced user id does not exist.422guildIdLike or the request body failed validation.429Rate limit hit (600 requests/minute per user). See the Retry-After header.
Reorder a guild's pages
PUT https://api.guild.xyz/guilds/{guildIdLike}/pages/order
Set the display order of the guild's pages. pageIds must be exactly the guild's current page ids as a permutation (no additions, removals or duplicates); otherwise 400 with code PAGE_ORDER_MISMATCH naming the missing and extra ids. Page references are preserved as stored; only their order changes. Prefer this to sending pages in PUT /guilds/{guildIdLike}, which replaces the list and drops any page left out.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id (UUID) or url name. string |
Body (GuildsPageOrderRequest):
| Field | Type | Description |
|---|---|---|
pageIds |
string (uuid)[] | The guild's pages in the new order. Must contain every page currently on the guild exactly once. |
Returns 200: The updated guild. (GuildsGuild)
| Field | Type | Description |
|---|---|---|
admins |
string[] | User ids. |
carousel (optional) |
object or GuildsGuildCarousel | |
color (optional) |
string | #rrggbb. |
contacts |
GuildsGuildContact[] | |
coverOpacity (optional) |
number (double) | 0-1. |
coverUrl (optional) |
string | |
createdAt |
string | ISO 8601. |
customization |
GuildsCustomization | customization — every field defaults to null. |
description (optional) |
string | Max 1500 characters. |
entry |
GuildsGuildEntry | The guild's entry gate (entry). |
featureFlags |
string[] | e.g. crm_with_socials, analytics, forms_v2, points_v2. |
guildPin (optional) |
object or GuildsGuildPin | |
id |
string (uuid) | |
isVerified |
boolean | |
legacyId (optional) |
integer (int64) | |
logoUrl (optional) |
string | |
mainPointsPlatformId (optional) |
string (uuid) | |
memberCount |
integer (int64) | |
name |
string | |
onboarding (optional) |
object or GuildsOnboarding | |
owner |
string (uuid) | |
pages |
GuildsGuildPageRef[] | |
permissions |
GuildsPermissions | permissions — nullable ids of the role/reward that grants read/write access, when the guild uses reward-gated permissions. |
platforms |
object[] | Connected platform configs (Discord, Telegram, POINTS, ...) — shape varies by type. Admins see every connected platform; other callers only platforms whose visibility is PUBLIC. |
rewards |
object[] | Reward configs — shape varies by type. Non-admin callers have system-visibility rewards (and NFT rewards not assigned to any role) filtered out. |
roleCount |
integer (int64) | |
socialLinks |
GuildsSocialLink[] | |
subscription (optional) |
object or GuildsGuildSubscription | |
tags |
string[] | |
updatedAt |
string | ISO 8601. |
urlName |
string |
400pageIds is not a permutation of the guild's pages (PAGE_ORDER_MISMATCH).401Not logged in.403Below admin access for this guild.404Guild not found.422guildIdLike failed validation, or pageIds is not an array of UUIDs.429Rate limit hit. See the Retry-After header.
Get a guild (legacy v2 path)
GET https://api.guild.xyz/v2/guilds/{guildIdLike}
Deprecated alias of GET /guilds/{guildIdLike}, kept for v2 API consumers. Identical behaviour and response; prefer the canonical path in new integrations.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id (UUID) or url name. string |
Returns 200: The guild. (GuildsGuild)
| Field | Type | Description |
|---|---|---|
admins |
string[] | User ids. |
carousel (optional) |
object or GuildsGuildCarousel | |
color (optional) |
string | #rrggbb. |
contacts |
GuildsGuildContact[] | |
coverOpacity (optional) |
number (double) | 0-1. |
coverUrl (optional) |
string | |
createdAt |
string | ISO 8601. |
customization |
GuildsCustomization | customization — every field defaults to null. |
description (optional) |
string | Max 1500 characters. |
entry |
GuildsGuildEntry | The guild's entry gate (entry). |
featureFlags |
string[] | e.g. crm_with_socials, analytics, forms_v2, points_v2. |
guildPin (optional) |
object or GuildsGuildPin | |
id |
string (uuid) | |
isVerified |
boolean | |
legacyId (optional) |
integer (int64) | |
logoUrl (optional) |
string | |
mainPointsPlatformId (optional) |
string (uuid) | |
memberCount |
integer (int64) | |
name |
string | |
onboarding (optional) |
object or GuildsOnboarding | |
owner |
string (uuid) | |
pages |
GuildsGuildPageRef[] | |
permissions |
GuildsPermissions | permissions — nullable ids of the role/reward that grants read/write access, when the guild uses reward-gated permissions. |
platforms |
object[] | Connected platform configs (Discord, Telegram, POINTS, ...) — shape varies by type. Admins see every connected platform; other callers only platforms whose visibility is PUBLIC. |
rewards |
object[] | Reward configs — shape varies by type. Non-admin callers have system-visibility rewards (and NFT rewards not assigned to any role) filtered out. |
roleCount |
integer (int64) | |
socialLinks |
GuildsSocialLink[] | |
subscription (optional) |
object or GuildsGuildSubscription | |
tags |
string[] | |
updatedAt |
string | ISO 8601. |
urlName |
string |
404No guild with this id/url name.422guildIdLike failed validation (must be a UUID or a 1-50 character url name).
Roles
Why members miss each role
GET https://api.guild.xyz/guilds/{guildIdLike}/access-insights
Guild admins only. Per requirement of each role, how many members pass, fail or have not been evaluated yet, read from the protocol's access tables. At most 1,000 members are examined; a larger guild is estimated and says sampled: true. "Not evaluated" is never counted as a failure. Cached for five minutes. 503 INSIGHTS_TIMEOUT when the data is too slow to read.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
Returns 200: Done. (AccessInsightsJson)
401Signed out.403Not a guild admin.404No such guild.503Too slow to read right now.
List roles
GET https://api.guild.xyz/roles
List roles filtered by exactly one of 'guildIdLike', 'pageIdLike', or 'rewardId'. Non-admin callers should still pass 'guildIdLike' even when filtering by 'pageIdLike'/'rewardId' alone — omitting it can trigger an unrelated 400 from an internal visibility check that runs after a successful lookup. For non-admin callers, roles they can't see are silently dropped from 'data' and a 'secrets' count of the dropped roles is added to the response.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
guildIdLike (optional) |
query | Id or url name of the guild to list roles of. string |
pageIdLike (optional) |
query | Id or url name of a page to list the roles of. string |
rewardId (optional) |
query | Only list roles that grant this reward. string (uuid) |
includeVisibility (optional) |
query | Guild-scoped listing only: compute each role's live visibility status instead of returning the last-synced stored value. boolean |
includeRequirements (optional) |
query | Include each role's requirements array. Defaults to true. boolean |
includeEnrichedRequirements (optional) |
query | Include requirements enriched with integration/display data (implies includeRequirements). boolean |
Returns 200: The matching roles. (RolesRoleListResponse)
| Field | Type | Description |
|---|---|---|
data |
RolesRoleResponse[] | |
secrets (optional) |
integer (int64) | Only present when the response was visibility-filtered for a non-admin caller: how many of the guild's SECRET/SELF_REVEAL roles the caller hasn't unlocked. Roles gated by an orphaned read reward are dropped from data without being counted here, so this is a subset of what was omitted, not the total. |
400Thrown by an internal visibility check, not this handler's own validation: a non-admin caller filtered by only 'pageIdLike' or only 'rewardId' without also passing 'guildIdLike'.404Guild not found, or page not found.422None of 'guildIdLike'/'pageIdLike'/'rewardId' given, or a param fails validation.503Visibility filtering failed transiently; safe to retry.
Create a role
POST https://api.guild.xyz/roles
Create a role in a guild (optionally attaching it to a page) and its Protocol access role. Requires guild admin, owner, or super-admin access.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
query | Id or url name of the guild to create the role in. string |
pageIdLike (optional) |
query | Id or url name of a page to attach the new role to. string |
Body (RolesCreateRoleRequest):
| Field | Type | Description |
|---|---|---|
description (optional) |
string | Max 1500 characters. |
imageUrl (optional) |
string | |
logic (optional) |
object or RolesLogic | |
name |
string | |
rewards (optional) |
string[] | Existing reward ids to attach to the role. Defaults to an empty list. |
tags (optional) |
string[] | Defaults to an empty list when omitted. |
Returns 201: The created role. (RolesRoleResponse)
| Field | Type | Description |
|---|---|---|
createdAt |
string | ISO 8601. |
description (optional) |
string | Max 1500 characters. |
guildId |
string (uuid) | |
id |
string (uuid) | |
imageUrl (optional) |
string | |
legacyId (optional) |
integer (int64) | Only set for roles carried over from the legacy (pre-v3) platform. |
logic |
RolesLogic | A role's combination logic. Unlike the rest of this file's schemas, logic's own keys are snake_case — the object is round-tripped straight to Protocol's role API. gate is one of AND, OR, ANY_OF, NESTED; any_of_num only matters when gate is ANY_OF; nested (an arbitrary requirement/role tree) can be present when gate is NESTED. |
memberCount |
integer (int64) | |
name |
string | |
pages |
RolesPageRef[] | |
permissions |
RolesPermissions | PERMISSION-reward gating for reading/writing this role, when configured — each is the id of the PERMISSION-type reward that unlocks it (the same id setRolePermission writes), not a requirement id. |
requirements (optional) |
object[] | Present on GET /roles results by default (omit it there by passing includeRequirements=false); always absent on the single-role endpoints (GET/POST/PUT /roles...), which strip it. |
rewards |
string[] | Reward ids attached to this role. |
tags |
string[] | |
updatedAt |
string | ISO 8601. |
visibility |
string | One of PUBLIC, SELF_REVEAL, SECRET, HIDDEN. |
400Malformed JSON body.401Not logged in.403Caller isn't an admin, owner, or super-admin of the guild.404Guild not found, or 'pageIdLike' doesn't resolve to a page in the guild.422Invalid query params, or the body fails role validation (e.g. missing 'name').429Rate limit hit. See the Retry-After header.
Get role limits and member numbers
GET https://api.guild.xyz/roles/claims
For the asked-about roles that are limited ("the first N members") or numbered ("#1, #2, … in the order members got it"): the limit, how many numbers are given out, and the caller's own number when logged in. Roles that are neither are left out, as are roles of other guilds and roles that aren't public unless the caller holds a number in them.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
guildIdLike |
query | Id or url name of the guild. string |
roleIds (optional) |
query | Comma-separated role ids, at most 500. Omit for every role of the guild. string |
Returns 200: The limited or numbered roles. (RolesClaimSummariesResponse)
| Field | Type | Description |
|---|---|---|
data |
RoleClaimSummary[] | Only the asked-about roles that are limited or numbered. |
404Guild not found.422Missing 'guildIdLike', or a role id isn't a UUID.502Protocol is unreachable.
Delete a role
DELETE https://api.guild.xyz/roles/{roleId}
Detach a role from a page; the role (and its Protocol access role) is only actually deleted once it has been removed from its last page. Requires guild admin, owner, or super-admin access.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
roleId |
path | The role's id. Unlike the other role endpoints, this path param isn't validated as a UUID at the request layer. string |
guildIdLike |
query | Id or url name of the guild the role belongs to. string |
pageIdLike |
query | Id or url name of the page to detach the role from. string |
Returns 204: The role was detached from the page (and deleted, if this was its last page).
401Not logged in.403Caller isn't an admin, owner, or super-admin of the guild.404Guild not found, page not found, or role not found.422Missing/invalid 'guildIdLike' or 'pageIdLike'.429Rate limit hit. See the Retry-After header.
Get a role
GET https://api.guild.xyz/roles/{roleId}
Fetch a single role by id. A 404 can mean the role truly doesn't exist, or that it exists but its visibility is restricted (SELF_REVEAL/SECRET/HIDDEN) and the caller lacks read access to it.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
roleId |
path | The role's id. string (uuid) |
guildIdLike |
query | Id or url name of the guild the role belongs to. string |
Returns 200: The role. (RolesRoleResponse)
| Field | Type | Description |
|---|---|---|
createdAt |
string | ISO 8601. |
description (optional) |
string | Max 1500 characters. |
guildId |
string (uuid) | |
id |
string (uuid) | |
imageUrl (optional) |
string | |
legacyId (optional) |
integer (int64) | Only set for roles carried over from the legacy (pre-v3) platform. |
logic |
RolesLogic | A role's combination logic. Unlike the rest of this file's schemas, logic's own keys are snake_case — the object is round-tripped straight to Protocol's role API. gate is one of AND, OR, ANY_OF, NESTED; any_of_num only matters when gate is ANY_OF; nested (an arbitrary requirement/role tree) can be present when gate is NESTED. |
memberCount |
integer (int64) | |
name |
string | |
pages |
RolesPageRef[] | |
permissions |
RolesPermissions | PERMISSION-reward gating for reading/writing this role, when configured — each is the id of the PERMISSION-type reward that unlocks it (the same id setRolePermission writes), not a requirement id. |
requirements (optional) |
object[] | Present on GET /roles results by default (omit it there by passing includeRequirements=false); always absent on the single-role endpoints (GET/POST/PUT /roles...), which strip it. |
rewards |
string[] | Reward ids attached to this role. |
tags |
string[] | |
updatedAt |
string | ISO 8601. |
visibility |
string | One of PUBLIC, SELF_REVEAL, SECRET, HIDDEN. |
404The guild or the role wasn't found, or the role isn't visible to the caller.422Missing/invalid 'guildIdLike', or 'roleId' isn't a UUID.503Visibility filtering failed transiently; safe to retry.
Update a role
PUT https://api.guild.xyz/roles/{roleId}
Partially update a role; only the fields present in the body are changed. Updating 'logic' also updates the role's Protocol access role, and can return 409 if the logic was changed concurrently by another request. Requires guild admin, owner, or super-admin access.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
roleId |
path | The role's id. string (uuid) |
guildIdLike |
query | Id or url name of the guild the role belongs to, used for the permission check. string |
Body (RolesUpdateRoleRequest):
| Field | Type | Description |
|---|---|---|
description (optional) |
string | |
imageUrl (optional) |
string | |
logic (optional) |
object or RolesLogic | |
name (optional) |
string | |
rewards (optional) |
string[] | Replaces the role's full reward id list. |
tags (optional) |
string[] |
Returns 200: The updated role. (RolesRoleResponse)
| Field | Type | Description |
|---|---|---|
createdAt |
string | ISO 8601. |
description (optional) |
string | Max 1500 characters. |
guildId |
string (uuid) | |
id |
string (uuid) | |
imageUrl (optional) |
string | |
legacyId (optional) |
integer (int64) | Only set for roles carried over from the legacy (pre-v3) platform. |
logic |
RolesLogic | A role's combination logic. Unlike the rest of this file's schemas, logic's own keys are snake_case — the object is round-tripped straight to Protocol's role API. gate is one of AND, OR, ANY_OF, NESTED; any_of_num only matters when gate is ANY_OF; nested (an arbitrary requirement/role tree) can be present when gate is NESTED. |
memberCount |
integer (int64) | |
name |
string | |
pages |
RolesPageRef[] | |
permissions |
RolesPermissions | PERMISSION-reward gating for reading/writing this role, when configured — each is the id of the PERMISSION-type reward that unlocks it (the same id setRolePermission writes), not a requirement id. |
requirements (optional) |
object[] | Present on GET /roles results by default (omit it there by passing includeRequirements=false); always absent on the single-role endpoints (GET/POST/PUT /roles...), which strip it. |
rewards |
string[] | Reward ids attached to this role. |
tags |
string[] | |
updatedAt |
string | ISO 8601. |
visibility |
string | One of PUBLIC, SELF_REVEAL, SECRET, HIDDEN. |
400Malformed JSON body.401Not logged in.403Caller isn't an admin, owner, or super-admin of the guild.404Guild not found, or role not found.409The role's logic changed concurrently while this request was updating it; retry.422Missing/invalid 'guildIdLike', 'roleId' isn't a UUID, or the body fails validation.429Rate limit hit. See the Retry-After header.
Get a role's member limit
GET https://api.guild.xyz/roles/{roleId}/claim-policy
The role's member limit and numbering, and how many numbers are given out. Requires guild admin, owner, or super-admin access.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
roleId |
path | The role's id. string (uuid) |
guildIdLike |
query | Id or url name of the guild the role belongs to. string |
Returns 200: The limit, or null. (RolesClaimPolicyResponse)
| Field | Type | Description |
|---|---|---|
data (optional) |
object or RoleClaimSummary |
401Not logged in.403Caller isn't an admin, owner, or super-admin of the guild.404Guild or role not found.
Set a role's member limit
PUT https://api.guild.xyz/roles/{roleId}/claim-policy
Limit the role to its first capacity members and/or number its members in the order they get it, optionally holding back the first reserved numbers for admins to assign (they count toward capacity, and members are numbered after them). A limit always numbers the members, and counts seats taken: a member who loses the role keeps their number and their seat, so a full role stays full. Turning numbering on numbers the current members in the order they got the role. Turning it off keeps every number. Requires guild admin, owner, or super-admin access.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
roleId |
path | The role's id. string (uuid) |
guildIdLike |
query | Id or url name of the guild the role belongs to. string |
Body (RoleClaimPolicy):
| Field | Type | Description |
|---|---|---|
capacity (optional) |
integer (int64) | Close the role after this many members. A limit numbers the members. |
numbered (optional) |
boolean | Number the members in the order they get the role. |
reserved (optional) |
integer (int64) | Hold back the first this-many numbers for admins to assign, say to the team. Counts toward capacity; members who get the role are numbered after them. |
Returns 200: The role's limit after the change. (RolesClaimPolicyResponse)
| Field | Type | Description |
|---|---|---|
data (optional) |
object or RoleClaimSummary |
400Malformed JSON body.401Not logged in.403Caller isn't an admin, owner, or super-admin of the guild.404Guild or role not found.422The limit isn't between 1 and 1,000,000,000, or the body has unknown fields.
List a role's member numbers
GET https://api.guild.xyz/roles/{roleId}/claims
The role's members in number order, with when each got their number. Requires guild admin, owner, or super-admin access.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
roleId |
path | The role's id. string (uuid) |
guildIdLike |
query | Id or url name of the guild the role belongs to. string |
offset (optional) |
query | Numbers to skip. Default 0. integer (int64) |
limit (optional) |
query | At most this many, up to 1000. Default 1000. integer (int64) |
Returns 200: The members, lowest number first. (RolesClaimsResponse)
| Field | Type | Description |
|---|---|---|
data |
RoleClaim[] |
401Not logged in.403Caller isn't an admin, owner, or super-admin of the guild.404Guild or role not found.
Free a reserved member number
DELETE https://api.guild.xyz/roles/{roleId}/claims/{number}
Take a reserved number back from its member. If they have the role they keep it, without a number. Requires guild admin, owner, or super-admin access.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
roleId |
path | The role's id. string (uuid) |
number |
path | A reserved number. integer (int32) |
guildIdLike |
query | Id or url name of the guild the role belongs to. string |
Returns 204: Freed (or it was already free).
401Not logged in.403Caller isn't an admin, owner, or super-admin of the guild.404Guild or role not found.422Not one of the role's reserved numbers.
Assign a reserved member number
PUT https://api.guild.xyz/roles/{roleId}/claims/{number}
Give a member one of the numbers the role holds back for admins (see reserved on the claim policy). A member who already had a number moves, and their old one goes to the next member who gets the role. It doesn't grant the role: the member gets it, with this number, once they qualify. Requires guild admin, owner, or super-admin access.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
roleId |
path | The role's id. string (uuid) |
number |
path | A reserved number, from 1 to the role's reserved. integer (int32) |
guildIdLike |
query | Id or url name of the guild the role belongs to. string |
Body (RolesAssignClaimRequest):
| Field | Type | Description |
|---|---|---|
member |
string | The member: an email, Discord name or wallet (0x…) they connected to Guild, or their Guild user id. |
Returns 200: Assigned. (RolesAssignClaimResponse)
| Field | Type | Description |
|---|---|---|
movedFrom (optional) |
integer (int32) | The number the member had before, free again. |
401Not logged in.403Caller isn't an admin, owner, or super-admin of the guild.404Guild or role not found, or no member has that email, Discord name or wallet.409Another member has this number, or several members have used that Discord name.422Not one of the role's reserved numbers, or a bad body.
Get a role's member count
GET https://api.guild.xyz/roles/{roleId}/member-count
Member count for the role, read from Protocol. Protocol evaluates access, so it is the only store of this number; if it cannot be reached the endpoint fails rather than answering with a stale one.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
roleId |
path | The role's id. string (uuid) |
Returns 200: The role's member count. (RolesMemberCountResponse)
| Field | Type | Description |
|---|---|---|
memberCount |
integer (int64) | The role's member count, from Protocol. |
422'roleId' isn't a UUID.502Protocol is unreachable or doesn't know this role.
List roles of a guild
GET https://api.guild.xyz/v1/guilds/{guildId}/roles
List roles of a guild, paginated. Unlike the public roles endpoint, this endpoint does not filter roles by visibility: SECRET/HIDDEN roles are included too, and each role's 'requirements' array is always present.
Auth: API key, as Authorization: Bearer <key>.
| Parameter | In | Description |
|---|---|---|
guildId |
path | Guild id or url name. string |
limit (optional) |
query | Defaults to 5, max 10. integer (int64) |
offset (optional) |
query | Defaults to 0. integer (int64) |
Returns 200: The guild's roles. (V1RolesRoleResponse[])
401Missing or invalid API key.403API key not valid for this guild, or no subscription.404No guild matches 'guildId'.422'limit' or 'offset' failed validation (e.g. 'limit' above 10).429Rate limit hit. See the Retry-After header.
Get member addresses
GET https://api.guild.xyz/v1/guilds/{guildId}/roles/{roleId}/member-addresses
Get the addresses of role members, paginated. The response may contain null entries: some members have no EVM wallet connected to their guild account, and returning them is necessary so the caller knows when to stop paginating.
Auth: API key, as Authorization: Bearer <key>.
| Parameter | In | Description |
|---|---|---|
guildId |
path | Guild id or url name. string |
roleId |
path | Role id. string |
limit (optional) |
query | Defaults to 100, max 1000. integer (int64) |
offset (optional) |
query | Defaults to 0. integer (int64) |
Returns 200: Addresses of role members. An entry is null when that member has no linked EVM address. (string[])
401Missing or invalid API key.403API key not valid for this guild, or no subscription. Also returned as 'No access to this role' when the role resolved from 'roleId' belongs to a different guild than 'guildId'.404No guild matches 'guildId', or no role matches 'roleId'.422'limit' or 'offset' failed validation (e.g. 'limit' above 1000).429Rate limit hit. See the Retry-After header.
Audit Log
Record an admin panel entry
POST https://api.guild.xyz/guilds/{guildIdLike}/admin/entry
Records an admin_panel.enter audit log event for the caller entering this guild's admin panel. The audit write is fire-and-forget — it happens in the background and its outcome does not affect the response — so this endpoint returns 204 even if the write itself later fails.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
Returns 204: Entry accepted. The audit log write itself happens asynchronously.
401Missing or invalid Guild session.403Caller is authenticated but is not an admin, owner, or super admin of this guild.404No guild matchesguildIdLike.429Rate limit hit. See the Retry-After header.
List a guild's audit log
GET https://api.guild.xyz/guilds/{guildIdLike}/audit-log
Lists this guild's audit log entries, newest first, each enriched with the acting user's display name, avatar, and primary connected identity. The total number of matching rows (ignoring limit/offset) is returned in the X-Total-Items header.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
startDate (optional) |
query | Inclusive ISO 8601 start timestamp. string |
endDate (optional) |
query | Inclusive ISO 8601 end timestamp; keep fixed while paging. string |
action (optional) |
query | Exact action, e.g. role.update. string |
resourceType (optional) |
query | Exact resource type, e.g. role. string |
actorId (optional) |
query | Only actions from this user. string (uuid) |
limit (optional) |
query | Max rows to return. Defaults to 50, min 1, max 100. integer (int64) |
offset (optional) |
query | Rows to skip, for pagination. Defaults to 0, min 0. integer (int64) |
Returns 200: The guild's audit log entries, newest first. (AuditLogEntryResponse[])
401Missing or invalid Guild session.403Caller is authenticated but is not an admin, owner, or super admin of this guild.404No guild matchesguildIdLike.422limitoroffsetfailed validation (not an integer, or out of range).429Rate limit hit. See the Retry-After header.
Access
Claim roles in a guild
POST https://api.guild.xyz/guilds/{guildIdLike}/claim-roles
Evaluate and claim one or more roles in a guild for the authenticated user. The caller must already be a member of the guild. Pass userId in the body to claim on behalf of a different user, but this only takes effect when the authenticated caller is a superAdmin — everyone else always claims for themselves. Pass claimInvisibleRoles=true to instead claim every secret / self-reveal role the caller currently has access to (admin roles excluded); in that mode roleIds may be omitted.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
claimInvisibleRoles (optional) |
query | When true, ignore roleIds and claim all secret/self-reveal roles the caller has access to instead. Defaults to false. boolean |
Body (AccessClaimRolesRequest):
| Field | Type | Description |
|---|---|---|
roleIds (optional) |
string[] | Role ids to claim. Required (and must be non-empty) unless the claimInvisibleRoles query param is true. Each entry is a role UUID. Defaults to an empty array. |
userId (optional) |
string (uuid) | Claim on behalf of a different user instead of the caller. Only takes effect when the authenticated caller is a superAdmin; every other caller always claims for themselves regardless of this field. |
Returns 200: Roles claimed. Entries that were skipped (e.g. an admin role filtered out of an invisible-role claim) still appear in claimedRoles, but carry only roleId — the controller's skipped marker is not forwarded. (AccessClaimRolesResponse)
| Field | Type | Description |
|---|---|---|
claimedRoles |
AccessClaimedRoleEntry[] | |
grantedPermissionRewardIds (optional) |
string[] | Present only when the claim cascaded into granting one or more PERMISSION (visibility) rewards, e.g. unlocking a secret role or page. |
message |
string | e.g. "Roles claimed successfully". |
success |
boolean |
400Malformed JSON request body, orroleIdswas empty whileclaimInvisibleRoleswas not true.401Not logged in.403The caller is not a member of this guild.404No guild matchesguildIdLike.422A path/query/body value failed validation (invalidguildIdLikeshape, a non-UUID entry inroleIds, an invaliduserId, orclaimInvisibleRolesnottrue/false).429Rate limit hit. See the Retry-After header.504The claim timed out, or the client disconnected before it finished. Safe to retry.
Join a guild
POST https://api.guild.xyz/join
Join an open guild as the authenticated user. Returns 200 with success: true both when the join succeeds and when the caller is already a member. Guilds whose entry type is private or gated currently reject the join with 403.
Auth: your signed-in Guild session (x-guild-auth-token).
Body (AccessJoinGuildRequest):
| Field | Type | Description |
|---|---|---|
guildId |
string (uuid) | |
ref (optional) |
string | Referral code from the invite link (?ref=). Optional; an unknown or unusable code never fails the join. |
Returns 200: Joined the guild, or the caller was already a member. (AccessJoinGuildResponse)
| Field | Type | Description |
|---|---|---|
message |
string | e.g. "Joined guild successfully" or "User is already a member of this guild". |
success |
boolean |
400Malformed JSON request body.401Not logged in.403The guild's entry type is private or gated; joining via this endpoint is not currently supported for it.404No guild matchesguildId.422Request body failed validation (missing/invalidguildId).429Rate limit hit. See the Retry-After header.
Leave a guild
POST https://api.guild.xyz/leave
Leave a guild as the authenticated user. The body's userId is validated but not otherwise used — the guild is always left on behalf of the authenticated caller, never on behalf of the supplied userId. Returns 200 with an empty body (no JSON) when the caller was not a member of the guild; this is not a 404.
Auth: your signed-in Guild session (x-guild-auth-token).
Body (AccessLeaveGuildRequest):
| Field | Type | Description |
|---|---|---|
guildId |
string (uuid) | |
userId |
string (uuid) |
Returns 200: Left the guild. When the caller was not a member, this is instead an empty body rather than this schema. (AccessLeaveGuildResponse)
| Field | Type | Description |
|---|---|---|
message |
string | |
success |
boolean |
400Malformed JSON request body.401Not logged in.404No guild matchesguildId.422Request body failed validation (missing/invaliduserIdorguildId).429Rate limit hit. See the Retry-After header.504The leave timed out, or was aborted before it finished. Safe to retry.
Get a user's guild memberships
GET https://api.guild.xyz/users/{userId}/memberships
List a user's enriched guild memberships, optionally scoped to a single guild via the guildId query param. Returns null (not an empty array or a 404) when the user has no memberships, or none matching guildId. Public endpoint — no authentication required, and exempt from the per-user rate limiter.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
userId |
path | Guild user id. string (uuid) |
guildId (optional) |
query | Guild id or url name to scope the result to a single guild. string |
includeMetadata (optional) |
query | Include guild/role/reward display metadata (name, image, description, etc.). Defaults to false. boolean |
includePoints (optional) |
query | Include the user's point platform balances for each guild. Defaults to false. boolean |
includeVisibility (optional) |
query | "none" (default, no visibility data) or "count" (include secret-role visibility counts). string |
detailedRoleIds (optional) |
query | Comma-separated role ids (at most 4 are used) to include detailed per-requirement evaluation data for. string |
Returns 200: The user's memberships, or null. (AccessMembership[])
404guildIdwas supplied but no guild matches it.422A path or query param failed validation (userIdnot a UUID, an invalidguildId, orincludeMetadata/includePoints/includeVisibilitynot one of their allowed values).504The lookup timed out, or the client disconnected before it finished. Safe to retry.
Launch
Cancel the launch
DELETE https://api.guild.xyz/guilds/{guildIdLike}/launch
Opens joins. Interest rows are kept.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (LaunchJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
The launch page of a coming-soon guild
GET https://api.guild.xyz/guilds/{guildIdLike}/launch
Optional session adds viewer. 404 when the guild has no launch.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (LaunchJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Create or edit the launch
PUT https://api.guild.xyz/guilds/{guildIdLike}/launch
Guild admins only. 409 GUILD_ALREADY_LIVE, 422 NUMBER_RANGE_NOT_RESERVED.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (LaunchJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Withdraw interest
DELETE https://api.guild.xyz/guilds/{guildIdLike}/launch/interest
Not for a pre-registration after launch.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (LaunchJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Notify me or pre-register
PUT https://api.guild.xyz/guilds/{guildIdLike}/launch/interest
PREREG needs Guild Plus.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (LaunchJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Launch now
POST https://api.guild.xyz/guilds/{guildIdLike}/launch/launch-now
Sets the launch time to now; the worker finishes within a minute.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (LaunchJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Pre-registered members
GET https://api.guild.xyz/guilds/{guildIdLike}/launch/preregistrations
Guild admins only. Notify-only members are a count.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (LaunchJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Pre-registered members as CSV
GET https://api.guild.xyz/guilds/{guildIdLike}/launch/preregistrations/export
Guild admins only. Columns: name, profile, reserved_number, status (joined or waiting), registered_at. At most 50,000 rows.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: CSV file.
401Signed out.403Not allowed.404Not found.503Not available yet.
Upcoming launches
GET https://api.guild.xyz/launches/upcoming
Verified or boosted guilds. Cached 5 minutes.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (LaunchJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
The caller's launch interests
GET https://api.guild.xyz/me/launches
Signed in.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: Done. (LaunchJson)
401Signed out.403Not allowed.404Not found.409Conflict.422Invalid input.503Not available yet.
Pin
Get a guild's Pin preview image CID
GET https://api.guild.xyz/guilds/{guildIdLike}/pin
Returns the IPFS CID of the Guild Pin preview image for guildAction, generating it (and Redis-caching the result for 24h) the first time it's requested. This is a preview only: it does not require authentication and does not check whether Guild Pin is enabled for the guild, unlike POST of the same path, which signs a mint authorization for the caller.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
guildAction (optional) |
query | One of JOINED_GUILD, IS_OWNER, IS_ADMIN. Defaults to JOINED_GUILD. string |
Returns 200: The Pin preview image CID. (PinCidResponse)
| Field | Type | Description |
|---|---|---|
cid |
string | IPFS CID of the Pin preview image, generated (and Redis-cached for 24h) the first time it's requested for this guild/guildAction pair. |
400The guild has no custom logo (still the default/guildLogosplaceholder) or nocustomization.accentColorset, so a Pin image can't be generated.404No guild matchesguildIdLike.422guildActionis present but not one ofJOINED_GUILD,IS_OWNER,IS_ADMIN, orguildIdLikefailed validation (must be a UUID or a 1-50 character url name).429Rate limit hit — only reachable when the caller has an active Guild session, since this route has no per-route auth. See the Retry-After header.500Unexpected error generating or pinning the preview image to IPFS.
Claim a guild Pin
POST https://api.guild.xyz/guilds/{guildIdLike}/pin
Builds and EIP-191-signs a mint payload for the caller's Guild Pin NFT for guildAction, against one of the caller's own linked EVM WALLET addresses. This does not submit an onchain transaction — the caller submits the returned signature in their own mint call. The caller must actually satisfy guildAction (guild membership for JOINED_GUILD/IS_ADMIN — admins get the same membership-gated Pin as regular members today, not an admin-specific check — or being the recorded guild owner for IS_OWNER), must not have already minted this action's Pin, and Guild Pin must be enabled and configured for a supported chain on this guild.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
Body (PinClaimRequest):
| Field | Type | Description |
|---|---|---|
guildAction (optional) |
string | One of JOINED_GUILD, IS_OWNER, IS_ADMIN. Defaults to JOINED_GUILD when omitted. |
userAddress |
string | EVM address to mint the Pin to. Must be a 0x-prefixed 20-byte hex address (case-insensitive) belonging to one of the caller's own linked EVM WALLET identities. |
Returns 200: The signed mint payload. (PinClaimResponse)
| Field | Type | Description |
|---|---|---|
adminFee |
string | Always "0" today — see adminTreasury. |
adminTreasury |
string | Always the zero address today — the contract supports an admin treasury cut, but it is unused. |
chainId |
integer (int64) | EVM chain id the Guild Pin contract is deployed on. |
cid |
string | IPFS CID of the Pin image. |
contractAddress |
string | 0x-prefixed Guild Pin contract address on chainId. |
createdAt |
integer (int64) | Unix seconds the claimed action occurred (join time for JOINED_GUILD/IS_ADMIN, guild creation time for IS_OWNER). |
guildAction |
string | The claimed action: one of JOINED_GUILD, IS_OWNER, IS_ADMIN. |
guildId |
string | The guild's id, re-encoded as a decimal uint256 string. |
guildName |
string | |
signature |
string | 0x-prefixed EIP-191 signature over the encoded payload hash; submit this in the mint transaction. |
timestamp |
integer (int64) | Unix seconds this payload was signed. |
userAddress |
string | The (lowercased) address the Pin will be minted to. |
userId |
string | The caller's Guild user id, re-encoded as a decimal uint256 string for the mint call. |
400Malformed JSON body; the guild's configured Guild Pin chain is unrecognized or has no RPC endpoint, Multicall3 address, or Guild Pin contract configured; or the guild has no custom logo/accent color set so the Pin image can't be generated.401Not logged in.403userAddressis not one of the caller's own linked EVMWALLETidentities.404No guild matchesguildIdLike, or the signed-in session's own user record no longer exists.422userAddressis missing or not a0x-prefixed 20-byte hex address, orguildActionis not one ofJOINED_GUILD,IS_OWNER,IS_ADMIN.429Rate limit hit. See the Retry-After header.500Guild Pin is not enabled for this guild; the caller already minted this guildAction's Pin; the caller doesn't satisfy guildAction's requirement; the mint creation timestamp couldn't be determined; or an unexpected upstream/RPC/IPFS error occurred.
Point Transactions
Get a user's point balance
GET https://api.guild.xyz/guilds/{guildIdLike}/points/{platformId}/balance/{userId}
Get a user's current balance and leaderboard rank on a POINTS platform. Public: no session or API key is required for a visible platform. Hidden systems require the owning guild's admin access. The platform must belong to the requested guild; negative balances are preserved.
Auth: not declared in the OpenAPI document; endpoint permissions still apply.
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
platformId |
path | Id of the POINTS platform to check the balance on. string (uuid) |
userId |
path | Guild user id to look up the balance for. string (uuid) |
Returns 200: The user's balance and rank. (PointTransactionsUserBalanceResponse)
| Field | Type | Description |
|---|---|---|
balance |
integer (int64) | Exact signed ledger balance, including negative amounts. |
rank |
integer (int64) | 1-based leaderboard rank among users with a positive balance on this platform; 0 when the user's own balance isn't positive. |
userId |
string (uuid) |
404Guild not found.429Rate limit hit. See the Retry-After header.
List point transactions
GET https://api.guild.xyz/guilds/{guildIdLike}/points/{platformId}/transactions
List the point_transaction ledger for a platform, newest first, optionally scoped to one user. Requires guild admin, owner, or super-admin access to guildIdLike. The target must be a POINTS platform belonging to that guild.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name; used for the admin permission check. string |
platformId |
path | Id of the POINTS platform whose transactions to list. string (uuid) |
userId (optional) |
query | Restrict the history to this user's transactions. string (uuid) |
limit (optional) |
query | Max rows to return. Defaults to 50. integer (int64) |
offset (optional) |
query | Rows to skip. Defaults to 0. integer (int64) |
Returns 200: The transaction history, newest first. (PointTransactionsTransaction[])
400The platform isn't a POINTS platform belonging to this guild.401Not logged in.403Caller isn't an admin, owner, or super-admin of the guild.404Guild not found.422userIdisn't a UUID, orlimit/offsetisn't a number.429Rate limit hit. See the Retry-After header.
Grant or deduct points
POST https://api.guild.xyz/guilds/{guildIdLike}/points/{platformId}/transactions
Create a single admin points-ledger transaction on a POINTS platform: a positive amount grants points, a negative amount deducts them. Returns the user's new balance. Requires guild admin, owner, or super-admin access.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
platformId |
path | Id of a POINTS platform belonging to this guild. string (uuid) |
Body (PointTransactionsTransactionInput):
| Field | Type | Description |
|---|---|---|
amount |
integer (int32) | Non-zero integer (must fit in a 32-bit signed integer); a positive amount grants points, a negative amount deducts them. |
note (optional) |
string | Optional free-text note stored on the ledger transaction. |
userId |
string (uuid) | The recipient/target user's Guild user id. |
Returns 201: The transaction was recorded; body is the user's new balance. (PointTransactionsBalanceResponse)
| Field | Type | Description |
|---|---|---|
balance |
integer (int64) | The user's total balance on this points platform after the transaction. |
400Malformed JSON body, orplatformIdisn't a POINTS platform belonging to this guild.401Not logged in.403Caller isn't an admin, owner, or super-admin of the guild.404Guild not found.422userIdisn't a UUID,amountisn't a non-zero integer, ornoteisn't a string.429Rate limit hit. See the Retry-After header.
Bulk grant or deduct points
POST https://api.guild.xyz/guilds/{guildIdLike}/points/{platformId}/transactions/bulk
Create up to 500 admin points-ledger transactions on a POINTS platform in one call; each entry grants (positive amount) or deducts (negative) points for its own userId. Requires guild admin, owner, or super-admin access.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id or url name. string |
platformId |
path | Id of a POINTS platform belonging to this guild. string (uuid) |
Body (PointTransactionsBulkCreateRequest):
| Field | Type | Description |
|---|---|---|
transactions |
PointTransactionsTransactionInput[] | Up to 500 entries. |
Returns 201: The transactions were recorded. (PointTransactionsBulkCreateResponse)
| Field | Type | Description |
|---|---|---|
inserted |
integer (int64) | Number of transactions actually inserted. |
400Malformed JSON body, orplatformIdisn't a POINTS platform belonging to this guild.401Not logged in.403Caller isn't an admin, owner, or super-admin of the guild.404Guild not found.422transactionsisn't an array, has more than 500 entries, or one of its entries fails validation (invaliduserId, non-zero-integeramount, or non-stringnote).429Rate limit hit. See the Retry-After header.
Member profiles
A guild's profile items
GET https://api.guild.xyz/guilds/{guildIdLike}/profile-items
Guild admins and owners. customSlots is 10 with the custom_profile_items feature plus the boost-level bonus (0, 5, 15 or 30).
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id (UUID) or url name. string |
Returns 200: The GuildProfileItemList. (GuildProfileItemList)
| Field | Type | Description |
|---|---|---|
canUploadCustom |
boolean | |
customSlots |
integer (int32) | |
customUsed |
integer (int64) | |
items |
GuildProfileItem[] |
401Signed out.403Not a guild admin.404No such guild.503PROFILES_UNAVAILABLE.
Create a guild profile item
POST https://api.guild.xyz/guilds/{guildIdLike}/profile-items
Guild admins and owners. Built-in starter art is open to any guild (50 active items). Uploaded art needs a free custom slot: 403 GUILD_PLAN_REQUIRED when the guild has none, 409 ITEM_SLOTS_FULL (with limit) when all are used.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id (UUID) or url name. string |
Body (GuildItemBody):
| Field | Type | Description |
|---|---|---|
art |
object | { builtin, tint? } or { asset }. |
kind |
string | decoration or effect. |
name |
string |
Returns 201: The item. (GuildProfileItem)
| Field | Type | Description |
|---|---|---|
archivedAt (optional) |
string | |
art |
ItemArt | |
createdAt |
string | |
guildId |
string | |
id |
string | |
kind |
string | |
name |
string |
401Signed out.403Not a guild admin, orGUILD_PLAN_REQUIRED.409ITEM_SLOTS_FULL.422Validation failed orINVALID_UPLOAD.503PROFILES_UNAVAILABLE.
Archive a guild profile item
DELETE https://api.guild.xyz/guilds/{guildIdLike}/profile-items/{itemId}
Guild admins and owners. The item stops being offered; members who hold it keep it equipped only until their next change.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id (UUID) or url name. string |
itemId |
path | Item id (UUID). string |
Returns 204: Archived.
401Signed out.403Not a guild admin.404No such item.503PROFILES_UNAVAILABLE.
Edit a guild profile item
PATCH https://api.guild.xyz/guilds/{guildIdLike}/profile-items/{itemId}
Guild admins and owners. Replacing uploaded art with uploaded art keeps its slot.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildIdLike |
path | Guild id (UUID) or url name. string |
itemId |
path | Item id (UUID). string |
Body (GuildItemPatchBody):
| Field | Type | Description |
|---|---|---|
art (optional) |
object | |
name (optional) |
string |
Returns 200: The item. (GuildProfileItem)
| Field | Type | Description |
|---|---|---|
archivedAt (optional) |
string | |
art |
ItemArt | |
createdAt |
string | |
guildId |
string | |
id |
string | |
kind |
string | |
name |
string |
401Signed out.403Not a guild admin, orGUILD_PLAN_REQUIRED.404No such item.409ITEM_SLOTS_FULL.422Validation failed orINVALID_UPLOAD.503PROFILES_UNAVAILABLE.
Whether a handle is free
GET https://api.guild.xyz/handles/{handle}/availability
available: false with reason INVALID, RESERVED or TAKEN.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
handle |
path | The handle to check. string |
Returns 200: The answer. (HandleAvailability)
| Field | Type | Description |
|---|---|---|
available |
boolean | |
handle |
string | |
reason (optional) |
string | INVALID, RESERVED or TAKEN when not available. |
503PROFILES_UNAVAILABLE.
My per-guild profiles
GET https://api.guild.xyz/me/guild-profiles
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: GuildProfileEntry[]. (GuildProfileEntry[])
401Signed out.
Remove my profile in a guild
DELETE https://api.guild.xyz/me/guild-profiles/{guildId}
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildId |
path | Guild id (UUID). string |
Returns 200: All the caller's per-guild profiles. (GuildProfileEntry[])
401Signed out.503PROFILES_UNAVAILABLE.
Set my nickname and avatar in a guild
PUT https://api.guild.xyz/me/guild-profiles/{guildId}
Plus, and the member must belong to the guild. Sending neither field removes it.
Auth: your signed-in Guild session (x-guild-auth-token).
| Parameter | In | Description |
|---|---|---|
guildId |
path | Guild id (UUID). string |
Body (GuildProfileBody):
| Field | Type | Description |
|---|---|---|
avatarUrl (optional) |
string | |
nickname (optional) |
string |
Returns 200: All the caller's per-guild profiles. (GuildProfileEntry[])
401Signed out.403PLUS_REQUIREDor not a member.422Validation failed orINVALID_UPLOAD.503PROFILES_UNAVAILABLE.
My profile settings
GET https://api.guild.xyz/me/profile
Everything the editor needs: fields, privacy, accounts, entitlement and limits. Refreshes the X handle first (best effort). Falls back to the legacy profile until the profile tables are applied.
Auth: your signed-in Guild session (x-guild-auth-token).
Returns 200: The ProfileSettings. (ProfileSettings)
| Field | Type | Description |
|---|---|---|
accounts |
ConnectedAccount[] | |
avatar (optional) |
object or SettingsAvatar | |
banner (optional) |
object or Banner | |
bio (optional) |
string | |
canonicalPath |
string | |
displayName (optional) |
string | |
ens (optional) |
object or SettingsEns | |
entitlement |
Entitlement | PlusEntitlement of types.ts (the handle hold lives with the handle). |
equipped |
SettingsEquipped | |
fallbackAvatarUrl (optional) |
string | |
guildProfiles |
GuildProfileEntry[] | |
handles |
SettingsHandles | |
limits |
ProfileLimits | |
links |
SettingsLink[] | |
location (optional) |
string | |
privacy |
SettingsPrivacy | |
profileLevel (optional) |
object or SettingsProfileLevel |