API reference
Base URL https://api.parleyai.app. JSON in and out. The SDKs wrap the client endpoints; your backend uses the server endpoints.
Authentication#
| Name | Type | Description |
|---|---|---|
| X-Parley-App-Key: pk_… | app key | Identifies the application environment. Public. |
| Authorization: Bearer ps_… | session | Customer session token from POST /v1/sessions. Expires after 90 days of inactivity. |
| Authorization: Bearer sk_… | secret key | Server API. Never use in clients. |
Browser requests must come from an allowed origin. Production keys return 402 plan_required without an active subscription.
Client endpoints#
| Name | Type | Description |
|---|---|---|
| GET /v1/config | app key | Branding, strings, AI name and invitations. |
| POST /v1/sessions | app key | Create or resume an anonymous session. Body: { platform, anonymousId?, appVersion?, locale?, device? }. |
| POST /v1/identify | session | { userId, userHash?, email?, name?, avatarUrl?, attributes? } |
| POST /v1/logout | session | Revoke the session. |
| GET /v1/customer · PATCH /v1/customer | session | Read or update the current customer. |
| GET /v1/conversations | session | The customer's conversations. |
| POST /v1/conversations | session | { subject?, message?: { body, attachmentIds?, idempotencyKey } } |
| GET /v1/conversations/:id | session | Conversation with the latest 50 messages. ?before= for older. |
| GET /v1/conversations/:id/messages | session | ?after= or ?before= ISO timestamps. |
| POST /v1/conversations/:id/messages | session | { body, attachmentIds?, idempotencyKey } — retries with the same key return the original message. |
| POST /v1/conversations/:id/read | session | Mark replies as read. |
| POST /v1/conversations/:id/handoff | session | Ask for a person. |
| POST /v1/attachments · GET /v1/attachments/:id | session | Signed upload slot · signed download URL. |
| POST /v1/events | session | { name, properties? } |
| POST · DELETE /v1/device-tokens | session | { provider: apns | fcm, token, apnsEnvironment? } |
| GET /v1/offers | session | Active offers for this customer. |
| POST /v1/engagement | session | { subjectType, subjectId, kind: impression | click | dismiss } |
| POST /v1/review-requests/eligibility | session | Whether to request a store review now. |
| GET /v1/stream | session | Server-sent events: message.created, message.updated. |
Example
Server endpoints#
| Name | Type | Description |
|---|---|---|
| GET /v1/server/customers/:userId | secret key | Customer with subscription and timestamps. |
| PUT /v1/server/customers/:userId | secret key | Create or update { email?, name?, avatarUrl?, attributes? }. |
| DELETE /v1/server/customers/:userId | secret key | Delete the customer and all their data. |
| POST /v1/server/customers/:userId/events | secret key | { name, properties? } |
Errors#
| Name | Type | Description |
|---|---|---|
| 400 | invalid_request | Validation failed; see issues. |
| 401 | unauthorized · identity_verification_failed | Missing/invalid key, session or userHash. |
| 402 | plan_required · limit_reached | Production key without a plan, or a plan limit. |
| 403 | forbidden | Origin not allowed or insufficient role. |
| 404 | not_found | Unknown id, or one that belongs to someone else. |
| 409 | already_identified | Call logout() before identifying a different user. |
| 413 | attachment_too_large | |
| 429 | rate_limited | Back off; see Retry-After. |
Rate limits#
Client endpoints: 120 requests per minute per IP and 60 per minute per customer; 20 new sessions per minute per IP. Server endpoints: 600 per minute per environment.
All list endpoints return at most 100 items. Message sends are idempotent by
idempotencyKey — always reuse the key when retrying.