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

Lists the enabled model catalog. Array order is the product's current model ranking (the first entry is the default model), not a stable contract; sort client-side if you need a fixed order.

Authorizations​

Responses​

Models list result, in the product's current ranking order

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, container instances, and team conversations 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