Skip to content

Auth, Tile management, and Tile hosting APIs for Poe Tiles.


Compatibility login with a linked Poe API key

POST
/auth/login

Request Body

application/json
JSON
{
  
"api_key": "string"
}

Responses

Login result

application/json
JSON
{
  
"success": true,
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true
  
}
}

Playground

Body

Samples


Start a poe-tiles CLI device-code login

POST
/auth/device-code/start

Request Body

application/json
JSON
{
  
"device_label": "string"
}

Responses

Device-code grant

application/json
JSON
{
  
"success": true,
  
"device_code": "string",
  
"user_code": "string",
  
"verification_uri": "string",
  
"verification_uri_complete": "string",
  
"expires_in": 0,
  
"interval": 0
}

Playground

Body

Samples


Poll a poe-tiles CLI device-code login

POST
/auth/device-code/poll

Request Body

application/json
JSON
{
  
"device_code": "string"
}

Responses

Device-code poll result

application/json
JSON
{
  
"success": true,
  
"status": "string"
}

Playground

Body

Samples


Start phone signup or login

POST
/auth/phone/start

Sends an OTP to the supplied phone number without revealing whether the number is already registered.

Request Body

application/json
JSON
{
  
"phoneNumber": "string",
  
"country": "string"
}

Responses

Challenge created and OTP sent

application/json
JSON
{
  
"success": true,
  
"challenge_id": "string",
  
"expires_at": 0,
  
"resend_available_in_ms": 0,
  
"dev_mode": true
}

Playground

Body

Samples


Confirm phone signup or login

POST
/auth/phone/confirm

Verifies the OTP, creates or selects the Tiles user by phone, creates a hashed session, and sets the existing session_token cookie.

Request Body

application/json
JSON
{
  
"challenge_id": "string",
  
"code": "string"
}

Responses

Phone confirmed and session created

application/json
JSON
{
  
"success": true,
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true
  
}
}

Playground

Body

Samples


Get current session

GET
/auth/session

Responses

Session result

application/json
JSON
{
  
"success": true,
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true
  
},
  
"is_admin": true,
  
"profile_complete": true
}

Playground

Samples


Logout and clear session

POST
/auth/logout

Responses

Logout success

application/json
JSON
{
  
"success": true
}

Playground

Samples


Get current points balance

GET
/usage/balance

Authorizations

Responses

Usage result

application/json
JSON
{
  
"success": true,
  
"pointBalance": 0
}

Playground

Samples


Get usage history

GET
/usage/points-history

Authorizations

Responses

Points history result

application/json
JSON
{
  
"success": true,
  
"history": [
  
  
{
  
  
  
"bot_name": "string",
  
  
  
"creation_time": 0,
  
  
  
"query_id": "string",
  
  
  
"cost_points": 0,
  
  
  
"usage_type": "string",
  
  
  
"additionalProperties": null
  
  
}
  
]
}

Playground

Samples


Models

Operations


List available models

GET
/models

Authorizations

Responses

Models list result

application/json
JSON
{
  
"success": true,
  
"models": [
  
  
{
  
  
  
"id": "string",
  
  
  
"description": "string",
  
  
  
"owned_by": "string",
  
  
  
"metadata": {
  
  
  
  
"display_name": "string",
  
  
  
  
"additionalProperties": null
  
  
  
},
  
  
  
"additionalProperties": null
  
  
}
  
]
}

Playground

Samples


List published Tiles

GET
/tiles

Paginated by opaque nextCursor. Ordered newest-first by the Tile registry's (updated_at, id) sort key.

Parameters

Query Parameters

limit
Type
integer
Minimum
1
Maximum
200
cursor
Type
string
Max Length
1000
creatorHandle
Type
string
Min Length
1
Max Length
255

Responses

Tiles list result

application/json
JSON
{
  
"success": true,
  
"tiles": [
  
  
{
  
  
  
"id": "string",
  
  
  
"handle": "string",
  
  
  
"creator_id": "string",
  
  
  
"creator_handle": "string",
  
  
  
"creator_display_name": "string",
  
  
  
"created_at": "string",
  
  
  
"updated_at": "string",
  
  
  
"profile_picture": "string",
  
  
  
"short_description": "string",
  
  
  
"display_name": "string",
  
  
  
"players": {
  
  
  
  
"min": 0,
  
  
  
  
"max": 0,
  
  
  
  
"recommended": {
  
  
  
  
  
"min": 0,
  
  
  
  
  
"max": 0
  
  
  
  
}
  
  
  
},
  
  
  
"preview_video": {
  
  
  
  
"url": "string",
  
  
  
  
"posterUrl": "string",
  
  
  
  
"bytes": 0
  
  
  
}
  
  
}
  
],
  
"nextCursor": "string"
}

Playground

Variables
Key
Value

Samples


Personalized 'for you' feed of Tiles with seeded pagination

GET
/tiles/for-you-feed

Top of the feed mixes the curated priority list with a seeded-random sample of recently updated Tiles (sample size = priority count, drawn from a pool of the 2*priority newest Tiles after excluding creators in the random-recent exclusion set — filtered first, then sliced, so a burst of excluded-creator publishes can't starve the slot). Pagination is stable for a given seed only as long as the underlying set of Tiles and the prioritized list are unchanged. New Tiles published or visibility flips between page fetches may shift positions; clients should treat duplicate or skipped Tiles across pages as expected.

Parameters

Query Parameters

seed
Type
string
Min Length
1
Max Length
256
cursor
Type
[ "integer", "null" ]
Minimum
0
limit
Type
integer
Minimum
1
Maximum
200

Responses

Seeded for-you feed page

application/json
JSON
{
  
"success": true,
  
"tiles": [
  
  
{
  
  
  
"id": "string",
  
  
  
"handle": "string",
  
  
  
"creator_id": "string",
  
  
  
"creator_handle": "string",
  
  
  
"creator_display_name": "string",
  
  
  
"created_at": "string",
  
  
  
"updated_at": "string",
  
  
  
"profile_picture": "string",
  
  
  
"short_description": "string",
  
  
  
"display_name": "string",
  
  
  
"players": {
  
  
  
  
"min": 0,
  
  
  
  
"max": 0,
  
  
  
  
"recommended": {
  
  
  
  
  
"min": 0,
  
  
  
  
  
"max": 0
  
  
  
  
}
  
  
  
},
  
  
  
"preview_video": {
  
  
  
  
"url": "string",
  
  
  
  
"posterUrl": "string",
  
  
  
  
"bytes": 0
  
  
  
}
  
  
}
  
],
  
"next_cursor": 0,
  
"seed": "string"
}

Playground

Variables
Key
Value

Samples


Get Tile details by ID

GET
/tiles/by-id/{tileId}

Parameters

Path Parameters

tileId*
Type
string
Required
Min Length
1

Responses

Tile details result

application/json
JSON
{
  
"success": true,
  
"tile": {
  
  
"id": "string",
  
  
"handle": "string",
  
  
"creator_id": "string",
  
  
"creator_handle": "string",
  
  
"creator_display_name": "string",
  
  
"created_at": "string",
  
  
"updated_at": "string",
  
  
"profile_picture": "string",
  
  
"short_description": "string",
  
  
"display_name": "string",
  
  
"players": {
  
  
  
"min": 0,
  
  
  
"max": 0,
  
  
  
"recommended": {
  
  
  
  
"min": 0,
  
  
  
  
"max": 0
  
  
  
}
  
  
},
  
  
"preview_video": {
  
  
  
"url": "string",
  
  
  
"posterUrl": "string",
  
  
  
"bytes": 0
  
  
},
  
  
"clientBundleId": "string",
  
  
"backendBundleId": "string",
  
  
"bundleUrl": "string",
  
  
"long_description": "string",
  
  
"media": [
  
  
  
{
  
  
  
  
"type": "string",
  
  
  
  
"url": "string"
  
  
  
}
  
  
],
  
  
"sourceBundleAvailable": true
  
}
}

Playground

Variables
Key
Value

Samples


Batch-get Tile summaries by ID

POST
/tiles/batch-by-id

Batch sibling of GET /tiles/by-id/{tileId}. Ids with no matching Tile are omitted from the response rather than erroring.

Request Body

application/json
JSON
{
  
"tileIds": [
  
  
"string"
  
]
}

Responses

Tile summaries for the requested ids

application/json
JSON
{
  
"success": true,
  
"tiles": [
  
  
{
  
  
  
"id": "string",
  
  
  
"handle": "string",
  
  
  
"creator_id": "string",
  
  
  
"creator_handle": "string",
  
  
  
"creator_display_name": "string",
  
  
  
"created_at": "string",
  
  
  
"updated_at": "string",
  
  
  
"profile_picture": "string",
  
  
  
"short_description": "string",
  
  
  
"display_name": "string",
  
  
  
"players": {
  
  
  
  
"min": 0,
  
  
  
  
"max": 0,
  
  
  
  
"recommended": {
  
  
  
  
  
"min": 0,
  
  
  
  
  
"max": 0
  
  
  
  
}
  
  
  
},
  
  
  
"preview_video": {
  
  
  
  
"url": "string",
  
  
  
  
"posterUrl": "string",
  
  
  
  
"bytes": 0
  
  
  
}
  
  
}
  
]
}

Playground

Body

Samples


List published versions for a Tile

GET
/tiles/by-id/{tileId}/versions

Paginated by opaque nextCursor. Ordered newest-first by the Tile registry's per-Tile version_number.

Parameters

Path Parameters

tileId*
Type
string
Required
Min Length
1

Query Parameters

limit
Type
integer
Minimum
1
Maximum
200
cursor
Type
string
Max Length
1000

Responses

Tile versions result

application/json
JSON
{
  
"success": true,
  
"versions": [
  
  
{
  
  
  
"versionNumber": 0,
  
  
  
"clientBundleId": "string",
  
  
  
"backendBundleId": "string",
  
  
  
"publishedAt": "string"
  
  
}
  
],
  
"nextCursor": "string"
}

Playground

Variables
Key
Value

Samples


Get Tile details with bundle URL

GET
/tiles/{userHandle}/{tileHandle}

Parameters

Path Parameters

userHandle*
Type
string
Required
Min Length
1
tileHandle*
Type
string
Required
Min Length
1

Responses

Tile details result

application/json
JSON
{
  
"success": true,
  
"tile": {
  
  
"id": "string",
  
  
"handle": "string",
  
  
"creator_id": "string",
  
  
"creator_handle": "string",
  
  
"creator_display_name": "string",
  
  
"created_at": "string",
  
  
"updated_at": "string",
  
  
"profile_picture": "string",
  
  
"short_description": "string",
  
  
"display_name": "string",
  
  
"players": {
  
  
  
"min": 0,
  
  
  
"max": 0,
  
  
  
"recommended": {
  
  
  
  
"min": 0,
  
  
  
  
"max": 0
  
  
  
}
  
  
},
  
  
"preview_video": {
  
  
  
"url": "string",
  
  
  
"posterUrl": "string",
  
  
  
"bytes": 0
  
  
},
  
  
"clientBundleId": "string",
  
  
"backendBundleId": "string",
  
  
"bundleUrl": "string",
  
  
"long_description": "string",
  
  
"media": [
  
  
  
{
  
  
  
  
"type": "string",
  
  
  
  
"url": "string"
  
  
  
}
  
  
],
  
  
"sourceBundleAvailable": true
  
}
}

Playground

Variables
Key
Value

Samples


Publish a Tile (cookie or Bearer auth)

POST
/tiles/publish

Authorizations

or

Responses

Publish result

application/json
JSON
{
  
"additionalProperties": null
}

Playground

Samples


Search the public Tile catalog

GET
/tiles/search

Authorizations

Parameters

Query Parameters

query*
Type
string
Required
Min Length
1
Max Length
500
limit
Type
integer
Minimum
1
Maximum
50
Default
20

Responses

Tile search results

application/json
JSON
{
  
"success": true,
  
"results": [
  
  
{
  
  
  
"id": "string",
  
  
  
"handle": "string",
  
  
  
"creator_id": "string",
  
  
  
"creator_handle": "string",
  
  
  
"creator_display_name": "string",
  
  
  
"created_at": "string",
  
  
  
"updated_at": "string",
  
  
  
"profile_picture": "string",
  
  
  
"short_description": "string",
  
  
  
"display_name": "string",
  
  
  
"players": {
  
  
  
  
"min": 0,
  
  
  
  
"max": 0,
  
  
  
  
"recommended": {
  
  
  
  
  
"min": 0,
  
  
  
  
  
"max": 0
  
  
  
  
}
  
  
  
},
  
  
  
"preview_video": {
  
  
  
  
"url": "string",
  
  
  
  
"posterUrl": "string",
  
  
  
  
"bytes": 0
  
  
  
}
  
  
}
  
],
  
"_timing": {
  
  
"total_ms": 0,
  
  
"trace_id": "string",
  
  
"worker_colo": "string"
  
}
}

Playground

Variables
Key
Value

Samples


Download a Tile's source-code bundle (cookie or Bearer auth)

GET
/tiles/by-id/{tileId}/source-bundle

Authorizations

or

Parameters

Path Parameters

tileId*
Type
string
Required
Min Length
1

Responses

Source bundle (gzipped tar). Body is the raw .tar.gz contents — Content-Type: application/gzip, Content-Disposition: attachment.

application/gzip

Playground

Variables
Key
Value

Samples


Rename one of your own Tiles.

PUT
/tiles/by-id/{tileId}/handle

Authorizations

or

Parameters

Path Parameters

tileId*
Type
string
Required
Min Length
1

Request Body

application/json
JSON
{
  
"handle": "string",
  
"publish_as_poe": true
}

Responses

Handle rewritten

application/json
JSON
{
  
"success": true
}

Playground

Variables
Key
Value
Body

Samples


Leave a top-level Tile instance

POST
/tiles/{typeId}/{instanceId}/leave

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
Max Length
1000
instanceId*
Type
string
Required
Min Length
1
Max Length
1000

Responses

Caller removed from the instance, or already not a member

application/json
JSON
{
  
"success": true,
  
"alreadyRemoved": true
}

Playground

Variables
Key
Value

Samples


Tile Bundles


Upload a tar.gz bundle for Tile hosting

POST
/tile-bundles/upload

Authorizations

Responses

Upload result

application/json
JSON
{
  
"additionalProperties": null
}

Playground

Samples


Search the user directory

GET
/users/search

Authorizations

Parameters

Query Parameters

q*
Type
string
Required
Min Length
1
Max Length
500
limit
Type
integer
Minimum
1
Maximum
50
Default
20
include
Type
string

Responses

User search results

application/json
JSON
{
  
"success": true,
  
"results": [
  
  
{
  
  
  
"user_id": "string",
  
  
  
"public_profile_id": "string",
  
  
  
"display_name": "string",
  
  
  
"profile_picture": "string",
  
  
  
"description": "string",
  
  
  
"show_playing": true,
  
  
  
"profile_version": 0,
  
  
  
"share_last_seen": true,
  
  
  
"relationship": {
  
  
  
  
"contact": true,
  
  
  
  
"block": true,
  
  
  
  
"mute": true
  
  
  
}
  
  
}
  
],
  
"_timing": {
  
  
"total_ms": 0,
  
  
"trace_id": "string",
  
  
"worker_colo": "string"
  
}
}

Playground

Variables
Key
Value

Samples


Get public profile, published Tiles, and recent plays

GET
/profiles/{publicProfileId}

Parameters

Path Parameters

publicProfileId*
Type
string
Required
Min Length
1

Query Parameters

include
Type
string

Responses

User profile result

application/json
JSON
{
  
"success": true,
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true,
  
  
"relationship": {
  
  
  
"contact": true,
  
  
  
"block": true,
  
  
  
"mute": true
  
  
}
  
},
  
"tiles": [
  
  
{
  
  
  
"id": "string",
  
  
  
"handle": "string",
  
  
  
"creator_id": "string",
  
  
  
"creator_handle": "string",
  
  
  
"creator_display_name": "string",
  
  
  
"created_at": "string",
  
  
  
"updated_at": "string",
  
  
  
"profile_picture": "string",
  
  
  
"short_description": "string",
  
  
  
"display_name": "string",
  
  
  
"players": {
  
  
  
  
"min": 0,
  
  
  
  
"max": 0,
  
  
  
  
"recommended": {
  
  
  
  
  
"min": 0,
  
  
  
  
  
"max": 0
  
  
  
  
}
  
  
  
},
  
  
  
"preview_video": {
  
  
  
  
"url": "string",
  
  
  
  
"posterUrl": "string",
  
  
  
  
"bytes": 0
  
  
  
}
  
  
}
  
],
  
"playing": [
  
  
{
  
  
  
"id": "string",
  
  
  
"handle": "string",
  
  
  
"creator_id": "string",
  
  
  
"creator_handle": "string",
  
  
  
"creator_display_name": "string",
  
  
  
"created_at": "string",
  
  
  
"updated_at": "string",
  
  
  
"profile_picture": "string",
  
  
  
"short_description": "string",
  
  
  
"display_name": "string",
  
  
  
"players": {
  
  
  
  
"min": 0,
  
  
  
  
"max": 0,
  
  
  
  
"recommended": {
  
  
  
  
  
"min": 0,
  
  
  
  
  
"max": 0
  
  
  
  
}
  
  
  
},
  
  
  
"preview_video": {
  
  
  
  
"url": "string",
  
  
  
  
"posterUrl": "string",
  
  
  
  
"bytes": 0
  
  
  
}
  
  
}
  
]
}

Playground

Variables
Key
Value

Samples


Get legacy handle-based user profile

GET
/users/{userHandle}

Parameters

Path Parameters

userHandle*
Type
string
Required
Min Length
1

Query Parameters

include
Type
string

Responses

User profile result

application/json
JSON
{
  
"success": true,
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true,
  
  
"relationship": {
  
  
  
"contact": true,
  
  
  
"block": true,
  
  
  
"mute": true
  
  
}
  
},
  
"tiles": [
  
  
{
  
  
  
"id": "string",
  
  
  
"handle": "string",
  
  
  
"creator_id": "string",
  
  
  
"creator_handle": "string",
  
  
  
"creator_display_name": "string",
  
  
  
"created_at": "string",
  
  
  
"updated_at": "string",
  
  
  
"profile_picture": "string",
  
  
  
"short_description": "string",
  
  
  
"display_name": "string",
  
  
  
"players": {
  
  
  
  
"min": 0,
  
  
  
  
"max": 0,
  
  
  
  
"recommended": {
  
  
  
  
  
"min": 0,
  
  
  
  
  
"max": 0
  
  
  
  
}
  
  
  
},
  
  
  
"preview_video": {
  
  
  
  
"url": "string",
  
  
  
  
"posterUrl": "string",
  
  
  
  
"bytes": 0
  
  
  
}
  
  
}
  
],
  
"playing": [
  
  
{
  
  
  
"id": "string",
  
  
  
"handle": "string",
  
  
  
"creator_id": "string",
  
  
  
"creator_handle": "string",
  
  
  
"creator_display_name": "string",
  
  
  
"created_at": "string",
  
  
  
"updated_at": "string",
  
  
  
"profile_picture": "string",
  
  
  
"short_description": "string",
  
  
  
"display_name": "string",
  
  
  
"players": {
  
  
  
  
"min": 0,
  
  
  
  
"max": 0,
  
  
  
  
"recommended": {
  
  
  
  
  
"min": 0,
  
  
  
  
  
"max": 0
  
  
  
  
}
  
  
  
},
  
  
  
"preview_video": {
  
  
  
  
"url": "string",
  
  
  
  
"posterUrl": "string",
  
  
  
  
"bytes": 0
  
  
  
}
  
  
}
  
]
}

Playground

Variables
Key
Value

Samples


Batch-get user info by internal user id

POST
/users/batch-by-id

Ids with no matching user are omitted from the response rather than erroring.

Authorizations

Request Body

application/json
JSON
{
  
"userIds": [
  
  
"string"
  
],
  
"include": [
  
  
"string"
  
]
}

Responses

User info for the requested ids

application/json
JSON
{
  
"success": true,
  
"users": [
  
  
{
  
  
  
"user_id": "string",
  
  
  
"public_profile_id": "string",
  
  
  
"display_name": "string",
  
  
  
"profile_picture": "string",
  
  
  
"description": "string",
  
  
  
"show_playing": true,
  
  
  
"profile_version": 0,
  
  
  
"share_last_seen": true,
  
  
  
"relationship": {
  
  
  
  
"contact": true,
  
  
  
  
"block": true,
  
  
  
  
"mute": true
  
  
  
}
  
  
}
  
]
}

Playground

Body

Samples


Search

Operations


Search indexed documents

GET
/search

Authorizations

Parameters

Query Parameters

q*
Type
string
Required
Min Length
1
Max Length
500
limit
Type
integer
Minimum
1
Maximum
100
Default
20

Responses

Search results

application/json
JSON
{
  
"success": true,
  
"results": [
  
  
{
  
  
  
"id": "string",
  
  
  
"instanceTypeId": "string",
  
  
  
"instanceId": "string",
  
  
  
"room": {
  
  
  
  
"typeId": "string",
  
  
  
  
"instanceId": "string"
  
  
  
},
  
  
  
"tableName": "string",
  
  
  
"itemKey": "string",
  
  
  
"sortKey": "string",
  
  
  
"text": "string",
  
  
  
"timestamp": 0
  
  
}
  
],
  
"_timing": {
  
  
"total_ms": 0,
  
  
"trace_id": "string",
  
  
"worker_colo": "string"
  
}
}

Playground

Variables
Key
Value

Samples


Client Metrics


Submit client-reported metrics

POST
/client-metrics

Accepts a bounded batch of client-reported metric events. The server records only metrics registered in its closed registry; invalid events are dropped and counted without rejecting the whole batch.

Authorizations

Request Body

application/json
JSON
{
  
"events": [
  
  
{
  
  
  
"metric": "string",
  
  
  
"attributes": {
  
  
  
  
"additionalProperties": null
  
  
  
},
  
  
  
"measurements": {
  
  
  
  
"additionalProperties": null
  
  
  
},
  
  
  
"trace_id": "string"
  
  
}
  
]
}

Responses

Metrics accepted

Playground

Body

Samples


Client Errors


Submit client-reported error events

POST
/client-errors

Accepts a bounded batch of client-reported error events, kernel-enriched with host-resolved tile identity. code is an open, free-form string (not a closed registry, unlike client-metrics); invalid events are dropped and counted without rejecting the whole batch.

Authorizations

Request Body

application/json
JSON
{
  
"events": [
  
],
  
"dropped": 0
}

Responses

Error events accepted

Playground

Body

Samples


Tile Metrics


Submit client-observed tile-metric events

POST
/tile-metrics

Accepts a bounded batch of client-observed tile-metric events (tile_opened / tile_ended / tile_replayed / chat_sheet_opened). The actor is derived from the session; the target (tileTypeId, tileInstanceId) and event details come from the client. Events are forwarded best-effort to the central ingest boundary, which authorizes membership and dedups at read time.

Authorizations

Request Body

application/json
JSON
{
  
"events": [
  
  
{
  
  
  
"eventType": "string",
  
  
  
"tileTypeId": "string",
  
  
  
"tileInstanceId": "string",
  
  
  
"dedupeKey": "string",
  
  
  
"occurredAt": 0,
  
  
  
"sessionId": "string",
  
  
  
"interactionKey": "string"
  
  
}
  
]
}

Responses

Events accepted

Playground

Body

Samples


Bug Reports


Submit an authenticated bug report

POST
/bug-reports

Accepts a bounded user-written bug report and optional root-app local-data dump, persists it (metadata in the database, dump in blob storage), then notifies the configured notifier best-effort.

Authorizations

Request Body

application/json
JSON
{
  
"description": "string",
  
"includeLocalData": true,
  
"context": {
  
  
"url": "string",
  
  
"userAgent": "string",
  
  
"platform": "string",
  
  
"managerRoute": "string",
  
  
"appBuild": "string"
  
},
  
"localDataDump": null
}

Responses

Bug report persisted

application/json
JSON
{
  
"success": true,
  
"bugReportId": "string"
}

Playground

Body

Samples


Get store instance version info

GET
/synced-store/instances/{typeId}/{instanceId}/info

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
instanceId*
Type
string
Required
Min Length
1

Responses

Store info

application/json
JSON
{
  
"success": true,
  
"version": 0,
  
"schemaVersion": 0,
  
"codeVersionId": "string",
  
"upgradeAvailable": true
}

Playground

Variables
Key
Value

Samples


Get store schema (tables, mutators, actions)

GET
/synced-store/instances/{typeId}/{instanceId}/schema

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
instanceId*
Type
string
Required
Min Length
1

Responses

Store schema

application/json
JSON
{
  
"success": true,
  
"schema": {
  
  
"type": "string",
  
  
"schemaVersion": 0,
  
  
"tables": {
  
  
  
"additionalProperties": null
  
  
},
  
  
"mutators": [
  
  
],
  
  
"actions": [
  
  
]
  
}
}

Playground

Variables
Key
Value

Samples


Upgrade store code version and trigger migrations

POST
/synced-store/instances/{typeId}/{instanceId}/upgrade

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
instanceId*
Type
string
Required
Min Length
1

Request Body

application/json
JSON
{
  
"codeVersionId": "string"
}

Responses

Upgrade result

application/json
JSON
{
  
"success": true,
  
"version": 0,
  
"schemaVersion": 0,
  
"codeVersionId": "string"
}

Playground

Variables
Key
Value
Body

Samples


Execute a server-side action

POST
/synced-store/instances/{typeId}/{instanceId}/action

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
instanceId*
Type
string
Required
Min Length
1

Request Body

application/json
JSON
{
  
"action_name": "string",
  
"action_input": null
}

Responses

Action result

application/json
JSON
{
  
"success": true,
  
"result": null
}

Playground

Variables
Key
Value
Body

Samples


Read one user-visible item from a store table

POST
/synced-store/instances/{typeId}/{instanceId}/get

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
instanceId*
Type
string
Required
Min Length
1

Request Body

application/json
JSON
{
  
"table_name": "string",
  
"key": "string"
}

Responses

Get result

application/json
JSON
{
  
"success": true,
  
"storeVersion": 0,
  
"found": true,
  
"value": null
}

Playground

Variables
Key
Value
Body

Samples


Scan user-visible items from a store table

POST
/synced-store/instances/{typeId}/{instanceId}/scan

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
instanceId*
Type
string
Required
Min Length
1

Request Body

application/json
JSON
{
  
"table_name": "string",
  
"prefix": {
  
  
"sortKey": "string",
  
  
"itemKey": "string"
  
},
  
"cursor": "string",
  
"limit": 0,
  
"reverse": true
}

Responses

Scan result

application/json
JSON
{
  
"success": true,
  
"storeVersion": 0,
  
"items": [
  
  
{
  
  
  
"itemKey": "string",
  
  
  
"sortKey": "string",
  
  
  
"value": null
  
  
}
  
],
  
"truncated": true,
  
"nextCursor": {
  
  
"sortKey": "string",
  
  
"itemKey": "string"
  
}
}

Playground

Variables
Key
Value
Body

Samples


Push mutations to a store instance

POST
/synced-store/instances/{typeId}/{instanceId}/mutate

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
instanceId*
Type
string
Required
Min Length
1

Request Body

application/json
JSON
{
  
"mutations": [
  
  
{
  
  
  
"name": "string",
  
  
  
"input": null
  
  
}
  
]
}

Responses

Mutation result

application/json
JSON
{
  
"success": true,
  
"version": 0
}

Playground

Variables
Key
Value
Body

Samples


Set the user-facing title of an app instance

PUT
/synced-store/instances/{typeId}/{instanceId}/title

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
instanceId*
Type
string
Required
Min Length
1

Request Body

application/json
JSON
{
  
"title": "string"
}

Responses

Title set

application/json
JSON
{
  
"success": true
}

Playground

Variables
Key
Value
Body

Samples


Invite users to play / use an app instance

POST
/synced-store/instances/{typeId}/{instanceId}/invite

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
instanceId*
Type
string
Required
Min Length
1

Request Body

application/json
JSON
{
  
"userIds": [
  
  
"string"
  
],
  
"appName": "string"
}

Responses

Invites dispatched

application/json
JSON
{
  
"success": true
}

Playground

Variables
Key
Value
Body

Samples


Test-only: seed a store instance with patches

POST
/internal/synced-store/instances/{typeId}/{instanceId}/seed

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
Max Length
1000
instanceId*
Type
string
Required
Min Length
1
Max Length
1000

Request Body

application/json
JSON
{
  
"patches": [
  
],
  
"newSchemaVersion": 0,
  
"newCodeVersionId": "string"
}

Responses

Seed result

application/json
JSON
{
  
"success": true,
  
"version": 0
}

Playground

Variables
Key
Value
Body

Samples


Test-only: upgrade a store instance's code version and trigger migrations

POST
/internal/synced-store/instances/{typeId}/{instanceId}/upgrade

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
Max Length
1000
instanceId*
Type
string
Required
Min Length
1
Max Length
1000

Request Body

application/json
JSON
{
  
"codeVersionId": "string"
}

Responses

Upgrade result

application/json
JSON
{
  
"success": true,
  
"version": 0,
  
"schemaVersion": 0,
  
"codeVersionId": "string"
}

Playground

Variables
Key
Value
Body

Samples


Test-only: run a system mutation on a store instance

POST
/internal/synced-store/instances/{typeId}/{instanceId}/mutate-as-system

Authorizations

Parameters

Path Parameters

typeId*
Type
string
Required
Min Length
1
Max Length
1000
instanceId*
Type
string
Required
Min Length
1
Max Length
1000

Request Body

application/json
JSON
{
  
"name": "string",
  
"input": null
}

Responses

Mutate-as-system result

application/json
JSON
{
  
"success": true,
  
"version": 0
}

Playground

Variables
Key
Value
Body

Samples


Reindex every Tile in the registry (backfill).

POST
/internal/reindex-tile-catalog

Authorizations

Responses

Backfill counts

application/json
JSON
{
  
"success": true,
  
"scanned": 0,
  
"indexed": 0,
  
"skipped": 0,
  
"errorCount": 0
}

Playground

Samples


Seed local-dev users and verified phone identifiers.

POST
/internal/dev/seed-users

Responses

Seeded dev users

application/json
JSON
{
  
"success": true,
  
"usersSeeded": 0,
  
"phoneIdentifiersSeeded": 0
}

Playground

Samples


In-region delegate: resolve an app's backend bundle metadata

POST
/central/resolve-bundle

Request Body

application/json
JSON
{
  
"storeTypeId": "string"
}

Responses

Bundle metadata, or a structured not-found result

application/json
JSON
{
  
"success": true,
  
"found": true,
  
"codeVersionId": "string",
  
"clientBundleId": "string",
  
"versionNumber": 0,
  
"isDevApp": true
}

Playground

Body

Samples


In-region delegate: read a user's profile from D1

POST
/central/get-user-info

Request Body

application/json
JSON
{
  
"userId": "string"
}

Responses

User info, or null when no users row exists

application/json
JSON
{
  
"success": true,
  
"user": {
  
  
"userId": "string",
  
  
"username": "string",
  
  
"publicProfileId": "string",
  
  
"displayName": "string",
  
  
"profilePicture": "string",
  
  
"_profileVersion": 0
  
}
}

Playground

Body

Samples


In-region delegate: batch-read user profiles from D1

POST
/central/get-user-info-many

Request Body

application/json
JSON
{
  
"userIds": [
  
  
"string"
  
]
}

Responses

User info rows aligned with the requested userIds

application/json
JSON
{
  
"success": true,
  
"users": [
  
  
{
  
  
  
"userId": "string",
  
  
  
"username": "string",
  
  
  
"publicProfileId": "string",
  
  
  
"displayName": "string",
  
  
  
"profilePicture": "string",
  
  
  
"_profileVersion": 0
  
  
}
  
]
}

Playground

Body

Samples


In-region delegate: write search documents to the index

POST
/central/index-search-documents

Request Body

application/json
JSON
{
  
"namespaces": [
  
  
"string"
  
],
  
"upserts": [
  
  
{
  
  
  
"id": "string",
  
  
  
"text": "string",
  
  
  
"timestamp": 0,
  
  
  
"version": 0,
  
  
  
"deleted": true,
  
  
  
"payload": null
  
  
}
  
],
  
"deletes": [
  
  
"string"
  
]
}

Responses

Indexing completed

application/json
JSON
{
  
"success": true
}

Playground

Body

Samples


Ingest trust boundary: validate + emit a tile-metric event

POST
/central/tile-metrics

Request Body

application/json
JSON
{
  
"event_type": "string",
  
"actor_user_id": "string",
  
"tile_type_id": "string",
  
"tile_instance_id": "string",
  
"dedupe_key": "string",
  
"occurred_at": 0,
  
"recipient_user_id": "string",
  
"session_id": "string",
  
"interaction_key": "string",
  
"actor_membership_asserted": true
}

Responses

Ingest outcome (best-effort; always 200 when well-formed)

application/json
JSON
{
  
"success": true,
  
"status": "string",
  
"reason": "string"
}

Playground

Body

Samples


Deletion


Process pending GDPR deletion requests (deploy hook)

POST
/run-pending-deletions

Request Body

application/json
JSON
{
  
"entries": [
  
  
{
  
  
  
"requestId": "string",
  
  
  
"userId": "string",
  
  
  
"prNumber": 0,
  
  
  
"prAuthor": "string",
  
  
  
"mergedAt": "string"
  
  
}
  
]
}

Responses

Per-entry deletion results

application/json
JSON
{
  
"success": true,
  
"results": [
  
  
{
  
  
  
"requestId": "string",
  
  
  
"status": "string",
  
  
  
"summary": {
  
  
  
  
"authRowsDeleted": 0,
  
  
  
  
"platformRowsDeleted": 0,
  
  
  
  
"userInstanceIndexRowsDeleted": 0,
  
  
  
  
"anonymizedTileIds": [
  
  
  
  
  
"string"
  
  
  
  
],
  
  
  
  
"searchDeindexed": true,
  
  
  
  
"userDeindexed": true,
  
  
  
  
"userManagerWiped": true,
  
  
  
  
"userSearchIndexWiped": true,
  
  
  
  
"selfDirectMessageWiped": true,
  
  
  
  
"bugReportDumpsWiped": true,
  
  
  
  
"agentsDeleted": 0,
  
  
  
  
"syncedStoresAnonymized": 0,
  
  
  
  
"syncedStoreInstancesAnonymized": [
  
  
  
  
  
{
  
  
  
  
  
  
"typeId": "string",
  
  
  
  
  
  
"instanceId": "string"
  
  
  
  
  
}
  
  
  
  
],
  
  
  
  
"syncedStoreAnonymizationDeferred": true,
  
  
  
  
"errors": [
  
  
  
  
  
{
  
  
  
  
  
  
"scope": "string",
  
  
  
  
  
  
"error": "string"
  
  
  
  
  
}
  
  
  
  
]
  
  
  
}
  
  
}
  
]
}

Playground

Body

Samples


Migration


Run pending deploy-time data-migration jobs (deploy hook)

POST
/run-migration-jobs

Request Body

application/json
JSON
{
  
"batchSize": 0
}

Responses

Batch result

application/json
JSON
{
  
"success": true,
  
"done": true,
  
"jobId": "string",
  
"cursor": "string",
  
"rowsWritten": 0
}

Playground

Body

Samples


Create a shareable invite URL for a store instance

POST
/invites

Authorizations

Request Body

application/json
JSON
{
  
"typeId": "string",
  
"instanceId": "string",
  
"leaderboardId": "string",
  
"expiresAt": "string"
}

Responses

Invite created

application/json
JSON
{
  
"success": true,
  
"code": "string",
  
"url": "string",
  
"leaderboardId": "string",
  
"expiresAt": "string"
}

Playground

Body

Samples


Fetch display info for an invite code

GET
/invites/{code}

Authorizations

Parameters

Path Parameters

code*
Type
string
Required
Min Length
1
Max Length
1000

Responses

Invite info

application/json
JSON
{
  
"success": true,
  
"code": "string",
  
"inviteType": "string",
  
"inviterUserHandle": "string",
  
"inviterDisplayName": "string",
  
"typeId": "string",
  
"instanceId": "string",
  
"viewerIsMember": true,
  
"targetKind": "string",
  
"targetDisplayName": "string",
  
"targetHandle": "string",
  
"targetTitle": "string",
  
"targetHasExplicitTitle": true,
  
"targetImageUrl": "string",
  
"roomMemberCount": 0,
  
"roomMemberPreview": [
  
  
{
  
  
  
"userId": "string",
  
  
  
"displayName": "string",
  
  
  
"profilePicture": "string"
  
  
}
  
],
  
"redirectUrl": "string",
  
"leaderboardId": "string",
  
"leaderboard": {
  
  
"success": true,
  
  
"code": "string",
  
  
"leaderboardId": "string",
  
  
"createdAt": "string",
  
  
"expiresAt": "string",
  
  
"tile": {
  
  
  
"typeId": "string",
  
  
  
"instanceId": "string",
  
  
  
"handle": "string",
  
  
  
"displayName": "string",
  
  
  
"profilePicture": "string",
  
  
  
"redirectUrl": "string"
  
  
},
  
  
"viewerIsMember": true,
  
  
"entries": [
  
  
  
{
  
  
  
  
"userId": "string",
  
  
  
  
"score": 0,
  
  
  
  
"displayScore": "string",
  
  
  
  
"updatedAt": 0,
  
  
  
  
"metadata": null
  
  
  
}
  
  
],
  
  
"users": [
  
  
  
{
  
  
  
  
"userId": "string",
  
  
  
  
"publicProfileId": "string",
  
  
  
  
"displayName": "string",
  
  
  
  
"profilePicture": "string"
  
  
  
}
  
  
]
  
}
}

Playground

Variables
Key
Value

Samples


Redeem an invite and join the target instance

POST
/invites/{code}/join

Authorizations

Parameters

Path Parameters

code*
Type
string
Required
Min Length
1
Max Length
1000

Responses

Joined instance

application/json
JSON
{
  
"success": true,
  
"redirectUrl": "string"
}

Playground

Variables
Key
Value

Samples


Fetch display info for a room invite

GET
/room-invite/{roomId}/{code}

Authorizations

Parameters

Path Parameters

roomId*
Type
string
Required
Min Length
1
Max Length
1000
code*
Type
string
Required
Min Length
1
Max Length
1000

Responses

Room invite info

application/json
JSON
{
  
"success": true,
  
"roomId": "string",
  
"code": "string",
  
"roomName": "string",
  
"inviterUserHandle": "string"
}

Playground

Variables
Key
Value

Samples


Redeem a room invite (add the caller to the room)

POST
/room-invite/{roomId}/{code}/redeem

Authorizations

Parameters

Path Parameters

roomId*
Type
string
Required
Min Length
1
Max Length
1000
code*
Type
string
Required
Min Length
1
Max Length
1000

Responses

Redeemed; caller is now a room member

application/json
JSON
{
  
"roomId": "string"
}

Playground

Variables
Key
Value

Samples


Add a target user as a member of (typeId, instanceId) without a share link

POST
/instance-members

Sibling of POST /invites — gated on the same caller membership check via isLiveInstanceMember. Target gate uses decideMessageSend(caller, target): 'deny' is rejected with a generic 403; 'allow' and 'warn' proceed. Self-add returns 422. The success payload echoes the decision so future UX can render a recipient-side warning for 'warn'.

Authorizations

Request Body

application/json
JSON
{
  
"typeId": "string",
  
"instanceId": "string",
  
"targetUserId": "string"
}

Responses

Member added (or already a member)

application/json
JSON
{
  
"success": true,
  
"decision": "string"
}

Playground

Body

Samples


Add multiple target users as members of (typeId, instanceId) by uid

POST
/instance-members/batch

UID-only batch sibling of POST /instance-members. Caller-level failures return one error response; target-level failures are returned per target.

Authorizations

Request Body

application/json
JSON
{
  
"typeId": "string",
  
"instanceId": "string",
  
"targetUserIds": [
  
  
"string"
  
]
}

Responses

Ordered per-target add results

application/json
JSON
{
  
"success": true,
  
"results": [
  
  
{
  
  
  
"success": true,
  
  
  
"targetUserId": "string",
  
  
  
"decision": "string"
  
  
}
  
]
}

Playground

Body

Samples


Add an agent as an agent-class member of (typeId, instanceId)

POST
/instance-agent-members

Agent-class sibling of POST /instance-members. The caller must be the agent's creator (agent store config.creatorUserId) AND a live member of the room. The agent's display row is built from its config name; membership is written with memberClass: 'agent'. Agent-existence/creator failures collapse to a generic 403.

Authorizations

Request Body

application/json
JSON
{
  
"typeId": "string",
  
"instanceId": "string",
  
"agentId": "string"
}

Responses

Agent added (or already a member)

application/json
JSON
{
  
"success": true
}

Playground

Body

Samples


Remove an agent member from (typeId, instanceId)

POST
/instance-agent-members/remove

Creator-only for v1 (room-admin removal widens later with the allowedAdders policy). Idempotent: returns alreadyRemoved: true when the agent is not a live member. Agent-existence/creator failures collapse to a generic 403.

Authorizations

Request Body

application/json
JSON
{
  
"typeId": "string",
  
"instanceId": "string",
  
"agentId": "string"
}

Responses

Agent removed (or already not a member)

application/json
JSON
{
  
"success": true,
  
"alreadyRemoved": true
}

Playground

Body

Samples


Create an agent owned by the caller (optionally add to a room)

POST
/instance-agents

Server-orchestrated agent creation (replaces the client-first option-C flow). Reserves the per-creator-unique name in the caller's manager registry, initializes the agent store with the caller as creator, and — when room is supplied — adds the agent as a memberClass:'agent' member (caller must be a live member; DMs refused). Duplicate name / full registry → 409.

Authorizations

Request Body

application/json
JSON
{
  
"name": "string",
  
"model": "string",
  
"tools": [
  
  
"string"
  
],
  
"toolModels": {
  
  
"additionalProperties": "string"
  
},
  
"room": {
  
  
"typeId": "string",
  
  
"instanceId": "string"
  
}
}

Responses

Agent created (and optionally added to the room)

application/json
JSON
{
  
"success": true,
  
"agentId": "string",
  
"addedToRoom": true,
  
"reused": true
}

Playground

Body

Samples


Delete an agent: remove it from all rooms + release its name

POST
/instance-agents/delete

Creator-only, like the single-room remove. Marks the registry claim deleting (a terminal state the add path refuses, so the agent cannot be re-added mid-delete), sweeps every room in the agent reverse index with $removeUser, then tombstones the claim (release runs LAST, only when every room removal succeeded — a partial failure returns failedRooms and keeps the deleting claim as the retry ticket; retrying re-attempts exactly the failed rooms). Deleting an already-deleted agent is an idempotent no-op. Agent-existence/creator failures collapse to a generic 403.

Authorizations

Request Body

application/json
JSON
{
  
"agentId": "string"
}

Responses

Sweep result (complete when failedRooms is empty)

application/json
JSON
{
  
"success": true,
  
"roomsRemoved": 0,
  
"failedRooms": [
  
  
{
  
  
  
"typeId": "string",
  
  
  
"instanceId": "string"
  
  
}
  
],
  
"registryReleased": true
}

Playground

Body

Samples


Chat rooms


Create a new chat room and add target users by uid

POST
/chat-rooms

Creates a new chat room with a server-minted instanceId, adds the creator, and adds up to 100 known uid targets. Does not accept phone numbers or contact-discovery inputs.

Authorizations

Request Body

application/json
JSON
{
  
"targetUserIds": [
  
  
"string"
  
]
}

Responses

New chat room id and ordered per-target add results

application/json
JSON
{
  
"success": true,
  
"instanceId": "string",
  
"results": [
  
  
{
  
  
  
"success": true,
  
  
  
"targetUserId": "string",
  
  
  
"decision": "string"
  
  
}
  
]
}

Playground

Body

Samples


Rooms


Validate tile-end results for an ended tile instance

POST
/rooms/tile-end

Validates the ended tile instance is in a room, the caller is a current room member, and per-player tile-end results mention exactly the current active roster.

Authorizations

Request Body

application/json
JSON
{
  
"players": {
  
  
"additionalProperties": "string"
  
},
  
"everyone": "string",
  
"typeId": "string",
  
"instanceId": "string"
}

Responses

Tile-end payload accepted

application/json
JSON
{
  
"success": true,
  
"players": [
  
  
{
  
  
  
"userId": "string",
  
  
  
"username": "string",
  
  
  
"displayName": "string",
  
  
  
"profilePicture": "string",
  
  
  
"result": "string"
  
  
}
  
],
  
"room": {
  
  
"storeTypeId": "string",
  
  
"instanceId": "string"
  
},
  
"parentRoom": {
  
  
"storeTypeId": "string",
  
  
"instanceId": "string"
  
}
}

Playground

Body

Samples


List agent tokens for the current user

GET
/agent-tokens

Authorizations

Responses

Token list

application/json
JSON
{
  
"success": true,
  
"tokens": [
  
  
{
  
  
  
"token_prefix": "string",
  
  
  
"label": "string",
  
  
  
"created_at": "string",
  
  
  
"expires_at": "string",
  
  
  
"scopes": [
  
  
  
  
{
  
  
  
  
  
"instance_type_id": "string",
  
  
  
  
  
"instance_id": "string"
  
  
  
  
}
  
  
  
]
  
  
}
  
]
}

Playground

Samples


Create a scoped agent token

POST
/agent-tokens

Authorizations

Request Body

application/json
JSON
{
  
"scopes": [
  
  
{
  
  
  
"instance_type_id": "string",
  
  
  
"instance_id": "string"
  
  
}
  
],
  
"label": ""
}

Responses

Token created

application/json
JSON
{
  
"success": true,
  
"token": "string"
}

Playground

Body

Samples


Delete an agent token

DELETE
/agent-tokens/{token}

Authorizations

Parameters

Path Parameters

token*
Type
string
Required
Min Length
1

Responses

Token deleted

application/json
JSON
{
  
"success": true
}

Playground

Variables
Key
Value

Samples


Look up a user by phone number (admin only)

POST
/admin/users/lookup-by-phone

Admin-only. Returns the full user record for the account that verified the given phone number, or 404 if none.

Authorizations

Request Body

application/json
JSON
{
  
"phone": "string"
}

Responses

The matched user

application/json
JSON
{
  
"success": true,
  
"user": {
  
  
"user_id": "string",
  
  
"username": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"phone_e164": "string",
  
  
"phone_verified_at": 0
  
}
}

Playground

Body

Samples


Search users by display name (admin only)

POST
/admin/users/search-by-display-name

Admin-only. Returns up to limit user records whose display name contains the given substring (case-insensitive). Backed by an unindexed scan; not intended to be efficient.

Authorizations

Request Body

application/json
JSON
{
  
"display_name": "string",
  
"limit": 0
}

Responses

The matched users (possibly empty)

application/json
JSON
{
  
"success": true,
  
"users": [
  
  
{
  
  
  
"user_id": "string",
  
  
  
"username": "string",
  
  
  
"public_profile_id": "string",
  
  
  
"display_name": "string",
  
  
  
"profile_picture": "string",
  
  
  
"description": "string",
  
  
  
"show_playing": true,
  
  
  
"phone_e164": "string",
  
  
  
"phone_verified_at": 0
  
  
}
  
]
}

Playground

Body

Samples


Add a phone number to the login allowlist (admin only)

POST
/admin/login-allowlist/add

Admin-only. Adds a phone number to the pre-launch login allowlist. Idempotent: re-adding an existing number is a no-op, signalled by already_present: true in the response.

Authorizations

Request Body

application/json
JSON
{
  
"phone": "string"
}

Responses

Number added (or already present)

application/json
JSON
{
  
"success": true,
  
"already_present": true
}

Playground

Body

Samples


Remove a phone number from the login allowlist (admin only)

POST
/admin/login-allowlist/remove

Admin-only. Removes a phone number from the pre-launch login allowlist. No-op if absent.

Authorizations

Request Body

application/json
JSON
{
  
"phone": "string",
  
"phone_lookup_key": "string"
}

Responses

Number removed

application/json
JSON
{
  
"success": true
}

Playground

Body

Samples


List the login allowlist (admin only)

GET
/admin/login-allowlist

Admin-only. Returns the current pre-launch login allowlist, newest-first. The list is bounded (small early-access set).

Authorizations

Responses

Current allowlist entries (possibly empty)

application/json
JSON
{
  
"success": true,
  
"entries": [
  
  
{
  
  
  
"phone_e164": "string",
  
  
  
"phone_lookup_key": "string",
  
  
  
"account_display_name": "string",
  
  
  
"added_via": "string",
  
  
  
"added_by_user_id": "string",
  
  
  
"added_by_display_name": "string",
  
  
  
"added_by_phone_e164": "string",
  
  
  
"added_at": 0
  
  
}
  
],
  
"admins": [
  
  
{
  
  
  
"phone_e164": "string",
  
  
  
"account_display_name": "string"
  
  
}
  
]
}

Playground

Samples


List persisted bug reports, newest first (admin only)

GET
/admin/bug-reports

Admin-only. Cursor-paginated: pass the previous page's nextCursor back as cursor. Accepts session-cookie or Bearer (Poe API key) auth.

Authorizations

Parameters

Query Parameters

limit
Type
integer
Minimum
1
Maximum
100
cursor
Type
string
Max Length
256

Responses

The newest bug reports (possibly empty)

application/json
JSON
{
  
"success": true,
  
"reports": [
  
  
{
  
  
  
"id": "string",
  
  
  
"reporter_user_id": "string",
  
  
  
"description": "string",
  
  
  
"include_local_data": true,
  
  
  
"url": "string",
  
  
  
"user_agent": "string",
  
  
  
"platform": "string",
  
  
  
"manager_route": "string",
  
  
  
"app_build": "string",
  
  
  
"trace_id": "string",
  
  
  
"created_at": 0
  
  
}
  
],
  
"nextCursor": "string"
}

Playground

Variables
Key
Value

Samples


Fetch a persisted bug report by id (admin only)

GET
/admin/bug-reports/{id}

Admin-only. Returns the persisted bug report, including the reporter's local-data dump when one was submitted. Accepts session-cookie or Bearer (Poe API key) auth.

Authorizations

Parameters

Path Parameters

id*
Type
string
Required
Min Length
1
Max Length
128

Responses

The persisted bug report

application/json
JSON
{
  
"success": true,
  
"report": {
  
  
"id": "string",
  
  
"reporter_user_id": "string",
  
  
"description": "string",
  
  
"include_local_data": true,
  
  
"url": "string",
  
  
"user_agent": "string",
  
  
"platform": "string",
  
  
"manager_route": "string",
  
  
"app_build": "string",
  
  
"trace_id": "string",
  
  
"created_at": 0,
  
  
"local_data_dump": "string"
  
}
}

Playground

Variables
Key
Value

Samples


Me


Get a single contact with the target user's public profile

GET
/me/contacts/{targetUserId}

Returns 200 + { edge, user } when an active contact edge exists, 404 otherwise. Gated on the caller having an active contact edge — the only single-uid lookup that returns a target user's profile.

Authorizations

Parameters

Path Parameters

targetUserId*
Type
string
Required
Min Length
1
Max Length
255

Responses

Contact with target user profile

application/json
JSON
{
  
"success": true,
  
"edge": {
  
  
"sourceUserId": "string",
  
  
"targetUserId": "string",
  
  
"edgeType": "string",
  
  
"state": "string",
  
  
"createdAt": 0,
  
  
"updatedAt": 0,
  
  
"phone": "string"
  
},
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true
  
}
}

Playground

Variables
Key
Value

Samples


Add a contact

PUT
/me/contacts/{targetUserId}

Idempotent. Re-adding an already-active contact returns 200 with the same updatedAt (no reordering). Gated on the caller and target both currently being members of (typeId, instanceId) — returns a single generic 403 if the target doesn't exist, the caller isn't a member, or the target isn't a member (all three collapse to the same response to avoid leaking uid existence or instance membership). In this product model, A's outgoing contacts list is A's send-permission list (see decideMessageSend in @lib/message-send), so unbounded uid-add would be unbounded send authorization.

Authorizations

Parameters

Path Parameters

targetUserId*
Type
string
Required
Min Length
1
Max Length
255

Request Body

application/json
JSON
{
  
"typeId": "string",
  
"instanceId": "string"
}

Responses

Contact added (or already active)

application/json
JSON
{
  
"success": true,
  
"edge": {
  
  
"sourceUserId": "string",
  
  
"targetUserId": "string",
  
  
"edgeType": "string",
  
  
"state": "string",
  
  
"createdAt": 0,
  
  
"updatedAt": 0,
  
  
"phone": "string"
  
},
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true,
  
  
"relationship": {
  
  
  
"contact": true,
  
  
  
"block": true,
  
  
  
"mute": true
  
  
}
  
}
}

Playground

Variables
Key
Value
Body

Samples


Remove a contact

DELETE
/me/contacts/{targetUserId}

Idempotent. Returns 200 + the soft-removed edge when a row was active; returns 204 (no body) when nothing was removed (row missing or already removed).

Authorizations

Parameters

Path Parameters

targetUserId*
Type
string
Required
Min Length
1
Max Length
255

Responses

Contact removed

application/json
JSON
{
  
"success": true,
  
"edge": {
  
  
"sourceUserId": "string",
  
  
"targetUserId": "string",
  
  
"edgeType": "string",
  
  
"state": "string",
  
  
"createdAt": 0,
  
  
"updatedAt": 0,
  
  
"phone": "string"
  
},
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true,
  
  
"relationship": {
  
  
  
"contact": true,
  
  
  
"block": true,
  
  
  
"mute": true
  
  
}
  
}
}

Playground

Variables
Key
Value

Samples


List the caller's outgoing contacts

GET
/me/contacts

Paginated by opaque nextCursor. Newest activity first (most recent updatedAt first). Each row inlines the target user's public profile (user). Rows whose target user row is missing (e.g. deleted account) are silently dropped, so a page can be shorter than limit and still have a nextCursor — treat the absence of nextCursor (not row count) as end-of-pages.

Authorizations

Parameters

Query Parameters

limit
Type
integer
Minimum
1
Maximum
200
cursor
Type
string
Max Length
1000

Responses

Page of contacts

application/json
JSON
{
  
"success": true,
  
"edges": [
  
  
{
  
  
  
"sourceUserId": "string",
  
  
  
"targetUserId": "string",
  
  
  
"edgeType": "string",
  
  
  
"state": "string",
  
  
  
"createdAt": 0,
  
  
  
"updatedAt": 0,
  
  
  
"phone": "string",
  
  
  
"user": {
  
  
  
  
"user_id": "string",
  
  
  
  
"public_profile_id": "string",
  
  
  
  
"display_name": "string",
  
  
  
  
"profile_picture": "string",
  
  
  
  
"description": "string",
  
  
  
  
"show_playing": true,
  
  
  
  
"profile_version": 0,
  
  
  
  
"share_last_seen": true
  
  
  
},
  
  
  
"last_seen_at": 0
  
  
}
  
],
  
"nextCursor": "string"
}

Playground

Variables
Key
Value

Samples


Bulk-add contacts by verified phone numbers

POST
/me/contacts/by-phone

Syncs a bounded phonebook batch into the caller's contacts. The server normalizes submitted phone numbers, resolves verified Poe users, adds outgoing contact edges where allowed, and returns hydrated contact rows for the matched phones. Failure reasons are collapsed by omission: malformed numbers, unregistered phones, self-adds, blocks, missing users, and contact-cap exhaustion are not distinguished per phone. The route only consumes rate-limit tokens for contacts it attempts to add.

Authorizations

Request Body

application/json
JSON
{
  
"phoneNumbers": [
  
  
"string"
  
]
}

Responses

Hydrated contacts that correspond to submitted phone numbers and are now active contacts.

application/json
JSON
{
  
"success": true,
  
"contacts": [
  
  
{
  
  
  
"phoneNumber": "string",
  
  
  
"contact": {
  
  
  
  
"sourceUserId": "string",
  
  
  
  
"targetUserId": "string",
  
  
  
  
"edgeType": "string",
  
  
  
  
"state": "string",
  
  
  
  
"createdAt": 0,
  
  
  
  
"updatedAt": 0,
  
  
  
  
"phone": "string",
  
  
  
  
"user": {
  
  
  
  
  
"user_id": "string",
  
  
  
  
  
"public_profile_id": "string",
  
  
  
  
  
"display_name": "string",
  
  
  
  
  
"profile_picture": "string",
  
  
  
  
  
"description": "string",
  
  
  
  
  
"show_playing": true,
  
  
  
  
  
"profile_version": 0,
  
  
  
  
  
"share_last_seen": true
  
  
  
  
},
  
  
  
  
"last_seen_at": 0
  
  
  
}
  
  
}
  
],
  
"addedCount": 0
}

Playground

Body

Samples


Check whether a contact is in a submitted device address book

POST
/me/contacts/{targetUserId}/phone-check

Returns whether targetUserId's verified phone is among the submitted phone numbers. Gated on the caller having an active contact edge to targetUserId (404 otherwise), returns only a boolean, and writes nothing — so it neither exposes the phone->user_id mapping nor re-adds contacts the way by-phone does. Powers the 'this contact will be re-added by sync' warning before removing a phone-synced contact.

Authorizations

Parameters

Path Parameters

targetUserId*
Type
string
Required
Min Length
1
Max Length
255

Request Body

application/json
JSON
{
  
"phoneNumbers": [
  
  
"string"
  
]
}

Responses

Whether the target is reachable via one of the submitted phones.

application/json
JSON
{
  
"success": true,
  
"onPhone": true
}

Playground

Variables
Key
Value
Body

Samples


List the caller's recently pushed dev / preview hosts

GET
/me/dev-hosts

Employee-only. Newest-first, capped at MAX_DEV_HOSTS_PER_USER. Populated by bun dev / /preview pushing to this user's account.

Authorizations

Responses

The caller's recent dev hosts

application/json
JSON
{
  
"hosts": [
  
  
{
  
  
  
"id": "string",
  
  
  
"url": "string",
  
  
  
"label": "string",
  
  
  
"source": "string",
  
  
  
"createdAt": 0
  
  
}
  
]
}

Playground

Samples


Push (upsert) a dev / preview host for the caller

POST
/me/dev-hosts

Employee-only. Idempotent per url: re-pushing the same URL floats it to the top. The model prunes back to MAX_DEV_HOSTS_PER_USER newest and drops entries older than the TTL.

Authorizations

Request Body

application/json
JSON
{
  
"url": "string",
  
"label": "string",
  
"source": "string"
}

Responses

Host upserted

application/json
JSON
{
  
"success": true,
  
"host": {
  
  
"id": "string",
  
  
"url": "string",
  
  
"label": "string",
  
  
"source": "string",
  
  
"createdAt": 0
  
}
}

Playground

Body

Samples


Add a block

PUT
/me/blocks/{targetUserId}

Idempotent. Re-adding an already-active block returns 200 with the same updatedAt (no reordering). Side effect: any active forward (caller → target, contact) edge is soft-removed (matches Twitter/X / Instagram block-auto-unfollows convention).

Authorizations

Parameters

Path Parameters

targetUserId*
Type
string
Required
Min Length
1
Max Length
255

Responses

Block added (or already active)

application/json
JSON
{
  
"success": true,
  
"edge": {
  
  
"sourceUserId": "string",
  
  
"targetUserId": "string",
  
  
"edgeType": "string",
  
  
"state": "string",
  
  
"createdAt": 0,
  
  
"updatedAt": 0,
  
  
"phone": "string"
  
},
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true,
  
  
"relationship": {
  
  
  
"contact": true,
  
  
  
"block": true,
  
  
  
"mute": true
  
  
}
  
}
}

Playground

Variables
Key
Value

Samples


Remove a block

DELETE
/me/blocks/{targetUserId}

Idempotent. Returns 200 + the soft-removed edge when a row was active; returns 204 (no body) when nothing was removed (row missing or already removed).

Authorizations

Parameters

Path Parameters

targetUserId*
Type
string
Required
Min Length
1
Max Length
255

Responses

Block removed

application/json
JSON
{
  
"success": true,
  
"edge": {
  
  
"sourceUserId": "string",
  
  
"targetUserId": "string",
  
  
"edgeType": "string",
  
  
"state": "string",
  
  
"createdAt": 0,
  
  
"updatedAt": 0,
  
  
"phone": "string"
  
},
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true,
  
  
"relationship": {
  
  
  
"contact": true,
  
  
  
"block": true,
  
  
  
"mute": true
  
  
}
  
}
}

Playground

Variables
Key
Value

Samples


List the caller's outgoing blocks

GET
/me/blocks

Paginated by opaque nextCursor. Newest activity first (most recent updatedAt first).

Authorizations

Parameters

Query Parameters

limit
Type
integer
Minimum
1
Maximum
200
cursor
Type
string
Max Length
1000

Responses

Page of blocks

application/json
JSON
{
  
"success": true,
  
"edges": [
  
  
{
  
  
  
"sourceUserId": "string",
  
  
  
"targetUserId": "string",
  
  
  
"edgeType": "string",
  
  
  
"state": "string",
  
  
  
"createdAt": 0,
  
  
  
"updatedAt": 0,
  
  
  
"phone": "string"
  
  
}
  
],
  
"nextCursor": "string"
}

Playground

Variables
Key
Value

Samples


Materialize the canonical direct message room

PUT
/me/direct-messages/{targetUserId}

Idempotent. On first call materializes the canonical DM instance for (caller, target) (writes participant rows into $users + $userInfo); subsequent calls no-op and return the same instanceId. Self materializes the caller's note-to-self DM; other-user DMs are gated on the caller having an active outgoing contact edge to the target — same send-permission model as decideMessageSend. Returns 403 (generic 'Cannot start DM') for missing contact edge, unknown target, or any block in either direction — distinguishing them would leak uid existence / block-state.

Authorizations

Parameters

Path Parameters

targetUserId*
Type
string
Required
Min Length
1
Max Length
255

Responses

DM instance materialized (or already exists)

application/json
JSON
{
  
"success": true,
  
"instanceId": "string"
}

Playground

Variables
Key
Value

Samples


Add a mute

PUT
/me/mutes/{targetUserId}

Idempotent. Re-adding an already-active mute returns 200 with the same updatedAt (no reordering).

Authorizations

Parameters

Path Parameters

targetUserId*
Type
string
Required
Min Length
1
Max Length
255

Responses

Mute added (or already active)

application/json
JSON
{
  
"success": true,
  
"edge": {
  
  
"sourceUserId": "string",
  
  
"targetUserId": "string",
  
  
"edgeType": "string",
  
  
"state": "string",
  
  
"createdAt": 0,
  
  
"updatedAt": 0,
  
  
"phone": "string"
  
},
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true,
  
  
"relationship": {
  
  
  
"contact": true,
  
  
  
"block": true,
  
  
  
"mute": true
  
  
}
  
}
}

Playground

Variables
Key
Value

Samples


Remove a mute

DELETE
/me/mutes/{targetUserId}

Idempotent. Returns 200 + the soft-removed edge when a row was active; returns 204 (no body) when nothing was removed (row missing or already removed).

Authorizations

Parameters

Path Parameters

targetUserId*
Type
string
Required
Min Length
1
Max Length
255

Responses

Mute removed

application/json
JSON
{
  
"success": true,
  
"edge": {
  
  
"sourceUserId": "string",
  
  
"targetUserId": "string",
  
  
"edgeType": "string",
  
  
"state": "string",
  
  
"createdAt": 0,
  
  
"updatedAt": 0,
  
  
"phone": "string"
  
},
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true,
  
  
"relationship": {
  
  
  
"contact": true,
  
  
  
"block": true,
  
  
  
"mute": true
  
  
}
  
}
}

Playground

Variables
Key
Value

Samples


List the caller's outgoing mutes

GET
/me/mutes

Paginated by opaque nextCursor. Newest activity first (most recent updatedAt first).

Authorizations

Parameters

Query Parameters

limit
Type
integer
Minimum
1
Maximum
200
cursor
Type
string
Max Length
1000

Responses

Page of mutes

application/json
JSON
{
  
"success": true,
  
"edges": [
  
  
{
  
  
  
"sourceUserId": "string",
  
  
  
"targetUserId": "string",
  
  
  
"edgeType": "string",
  
  
  
"state": "string",
  
  
  
"createdAt": 0,
  
  
  
"updatedAt": 0,
  
  
  
"phone": "string"
  
  
}
  
],
  
"nextCursor": "string"
}

Playground

Variables
Key
Value

Samples


Bulk lookup of outgoing edge state toward multiple users

GET
/me/relationships

Returns one row per unique userId in the ids param. Phantom IDs return all-false. ids is comma-separated; up to 50 unique IDs per request.

Authorizations

Parameters

Query Parameters

ids*
Type
string
Required
Min Length
1
Max Length
12800

Responses

Per-target relationship summary

application/json
JSON
{
  
"success": true,
  
"relationships": [
  
  
{
  
  
  
"userId": "string",
  
  
  
"contact": true,
  
  
  
"block": true,
  
  
  
"mute": true
  
  
}
  
]
}

Playground

Variables
Key
Value

Samples


App instances the caller and the target both belong to

GET
/me/shared-rooms/{targetUserId}

Returns the instances both the caller and targetUserId are currently members of, newest-first by the caller's join time, capped at the server maximum. Returns an empty list (not an error) for the self case and when either party has blocked the other. Materialized 1:1 DM instances are included so contact-add affordances can use them as shared-instance proof.

Authorizations

Parameters

Path Parameters

targetUserId*
Type
string
Required
Min Length
1
Max Length
255

Responses

Shared rooms (instance IDs only)

application/json
JSON
{
  
"success": true,
  
"rooms": [
  
  
{
  
  
  
"typeId": "string",
  
  
  
"instanceId": "string",
  
  
  
"joinedAt": "string"
  
  
}
  
]
}

Playground

Variables
Key
Value

Samples


People from the caller's recent rooms

GET
/me/room-people

One cursor-paginated page of distinct other members of the caller's recent small, non-DM instances, newest-first by the caller's join time. Each person carries the hydrated user, an isContact flag, a representative sharedInstance (the add-gating context for PUT /me/contacts), and lastSharedAt. Blocked/blocking users (either direction) are excluded; excludeContacts=true also drops existing contacts. nextCursor is null once the caller's instances are exhausted; an empty people with a non-null nextCursor is valid (a page of all-DM/all-crowd/solo instances) — keep paging. Cross-page dedup is the client's job.

Authorizations

Parameters

Query Parameters

cursor
Type
string
Max Length
1000
excludeContacts
Type
string
Max Length
8

Responses

One page of room people

application/json
JSON
{
  
"success": true,
  
"people": [
  
  
{
  
  
  
"user": {
  
  
  
  
"user_id": "string",
  
  
  
  
"public_profile_id": "string",
  
  
  
  
"display_name": "string",
  
  
  
  
"profile_picture": "string",
  
  
  
  
"description": "string",
  
  
  
  
"show_playing": true,
  
  
  
  
"profile_version": 0,
  
  
  
  
"share_last_seen": true
  
  
  
},
  
  
  
"isContact": true,
  
  
  
"sharedInstance": {
  
  
  
  
"typeId": "string",
  
  
  
  
"instanceId": "string"
  
  
  
},
  
  
  
"lastSharedAt": "string"
  
  
}
  
],
  
"nextCursor": "string"
}

Playground

Variables
Key
Value

Samples


Update the caller's editable profile fields

PATCH
/me/profile

description, show_playing, and display_name are all optional and updated independently when present. An empty body is a 200 no-op. Empty / whitespace-only description clears the bio (stored as NULL); empty / whitespace-only display_name is rejected (400). description is capped at PROFILE_DESCRIPTION_MAX_LENGTH, display_name at DISPLAY_NAME_MAX_LENGTH.

Authorizations

Request Body

application/json
JSON
{
  
"description": "string",
  
"show_playing": true,
  
"share_last_seen": true,
  
"display_name": "string"
}

Responses

Profile updated; returns the canonical user record.

application/json
JSON
{
  
"success": true,
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true
  
}
}

Playground

Body

Samples


Record the caller as present now (global last-seen)

PUT
/me/presence

Body-less. Server-stamps the caller's global last_seen_at (coalesced, so a rapid repeat is a no-op). Read back — gated by symmetric share_last_seen — via GET /me/contacts.

Authorizations

Responses

Presence recorded (or coalesced no-op).

application/json
JSON
{
  
"success": true
}

Playground

Samples


Upload the caller's profile picture

POST
/me/profile-picture

Raw image bytes in the request body; Content-Type declares the format (image/png, image/jpeg, or image/webp). Validated and stored as a self-hosted /blobs/{hash}.{ext} URL on the user's record. Rejects unsupported types (unsupported_image_type), oversized payloads (image_too_large), and bytes that don't match the declared type (invalid_image).

Authorizations

Responses

Profile picture set; returns the canonical user record.

application/json
JSON
{
  
"success": true,
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true
  
}
}

Playground

Samples


Remove the caller's profile picture

DELETE
/me/profile-picture

Clears the caller's profile picture (sets it to null). Idempotent — clearing an already-absent picture returns 200.

Authorizations

Responses

Profile picture cleared; returns the canonical user.

application/json
JSON
{
  
"success": true,
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true
  
}
}

Playground

Samples


Mark the caller's onboarding (NUX) as complete

POST
/me/onboarding/complete

Stamps users.onboarded_at so the onboarding gate stops showing the NUX. Idempotent — a repeat call keeps the original timestamp. No request body.

Authorizations

Responses

Onboarding marked complete; returns the user record.

application/json
JSON
{
  
"success": true,
  
"user": {
  
  
"user_id": "string",
  
  
"public_profile_id": "string",
  
  
"display_name": "string",
  
  
"profile_picture": "string",
  
  
"description": "string",
  
  
"show_playing": true,
  
  
"profile_version": 0,
  
  
"share_last_seen": true
  
}
}

Playground

Samples


Start phone verification

POST
/me/phone/start-verification

Initiates SMS-OTP verification for the supplied E.164 phone number. Returns the verification's expiry timestamp; the actual code arrives via SMS. Subject to per-IP (pre-auth) and per-user (post-auth) rate limits.

Authorizations

Request Body

application/json
JSON
{
  
"phoneNumber": "string"
}

Responses

Verification started; SMS sent

application/json
JSON
{
  
"expiresAt": 0,
  
"resendAvailableInMs": 0,
  
"devMode": true
}

Playground

Body

Samples


Confirm phone verification

POST
/me/phone/confirm-verification

Submits the SMS code; on success, the caller's verified phone is registered in the identifier index. Code validation is delegated to the provider; a local phone_verifications row binds the verification to the originating user_id so a different authed user can't claim a code that legitimately reached the target phone.

Authorizations

Request Body

application/json
JSON
{
  
"phoneNumber": "string",
  
"code": "string"
}

Responses

Code accepted; phone now verified for the caller

application/json
JSON
{
  
"verified": true,
  
"phoneE164": "string"
}

Playground

Body

Samples


Get the caller's verified phone status

GET
/me/phone

Returns whether the caller has a verified phone and, if so, the canonical E.164 string. The full E.164 is returned because it's the user's own self-disclosed identifier (displayed in account settings, same trust class as their email).

Authorizations

Responses

Phone status

application/json
JSON
{
  
"hasVerifiedPhone": true,
  
"phoneE164": "string",
  
"onboardedAt": 0,
  
"displayName": "string"
}

Playground

Samples


Get linked Poe account state

GET
/me/poe-link

Poe link state

application/json
JSON
{
  
"success": true,
  
"link": {
  
  
"linked": true,
  
  
"poe_user_id": "string",
  
  
"poe_handle": "string",
  
  
"poe_display_name": "string",
  
  
"poe_profile_picture": "string",
  
  
"api_key_expires_at": "string",
  
  
"pay_with_points_enabled": true
  
},
  
"oauth_connect_enabled": true
}

Unlink the current user's Poe account

DELETE
/me/poe-link

Unlinked Poe account

application/json
JSON
{
  
"success": true
}

Link a Poe account with a Poe API key

POST
/me/poe-link/api-key

Authorizations

Request Body

application/json
JSON
{
  
"api_key": "string"
}

Responses

Linked Poe account state

application/json
JSON
{
  
"success": true,
  
"link": {
  
  
"linked": true,
  
  
"poe_user_id": "string",
  
  
"poe_handle": "string",
  
  
"poe_display_name": "string",
  
  
"poe_profile_picture": "string",
  
  
"api_key_expires_at": "string",
  
  
"pay_with_points_enabled": true
  
},
  
"oauth_connect_enabled": true
}

Playground

Body

Samples


Enable pay-with-points for the linked Poe account

POST
/me/poe-link/pay-with-points/enable

Authorizations

Responses

Updated Poe link state

application/json
JSON
{
  
"success": true,
  
"link": {
  
  
"linked": true,
  
  
"poe_user_id": "string",
  
  
"poe_handle": "string",
  
  
"poe_display_name": "string",
  
  
"poe_profile_picture": "string",
  
  
"api_key_expires_at": "string",
  
  
"pay_with_points_enabled": true
  
}
}

Playground

Samples


Whether the caller can make Poe-backed bot/agent calls

GET
/me/poe-bot-access

Authorizations

Responses

Bot-access capability

application/json
JSON
{
  
"success": true,
  
"can_use": true
}

Playground

Samples


List the caller's own live agents

GET
/me/agents

Authorizations

Responses

The caller's live agents (newest-first)

application/json
JSON
{
  
"success": true,
  
"agents": [
  
  
{
  
  
  
"agentId": "string",
  
  
  
"name": "string",
  
  
  
"model": "string"
  
  
}
  
]
}

Playground

Samples


Get the authenticated user's subscription status

GET
/me/subscription

Authorizations

Responses

Subscription status

application/json
JSON
{
  
"success": true,
  
"status": "string",
  
"entitled": true,
  
"tier": "string",
  
"period": "string",
  
"currentPeriodEndMs": 0,
  
"cancelAtPeriodEnd": true,
  
"platform": "string"
}

Playground

Samples


Create a Stripe Checkout session for the authenticated user

POST
/me/subscription/checkout

Authorizations

Request Body

application/json
JSON
{
  
"tier": "string"
}

Responses

Checkout session

application/json
JSON
{
  
"success": true,
  
"checkoutUrl": "string"
}

Playground

Body

Samples


Create a Stripe Customer Portal session for the authenticated user

POST
/me/subscription/portal

Authorizations

Request Body

application/json
JSON
{
  
"returnTo": "string"
}

Responses

Portal session

application/json
JSON
{
  
"success": true,
  
"portalUrl": "string"
}

Playground

Body

Samples


Powered by VitePress OpenAPI