Summary and recommendation
Gorgias exposes a REST API at `https://{account}.gorgias.com/api` - note the account-specific subdomain; there is no shared global endpoint. Authentication is HTTP Basic Auth using the account owner's email as the username and an API token generated in Settings → REST API as the password.
The token is account-scoped, not agent-scoped, so it must be stored and rotated with care. The `/api/users` endpoint manages agent records only; end-customer contacts are a separate resource under `/api/customers`. No SCIM 2.0 endpoint exists on any plan, meaning identity graph synchronization from an IdP requires a custom REST integration against these endpoints.
Rate limits are plan-tiered: 2 req/s on Starter and Basic, 10 req/s on Pro and Advanced, with custom limits negotiable on Enterprise. All 429 responses include `Retry-After` and `X-RateLimit-Reset` headers - implement exponential back-off accordingly.
API quick reference
| Has user API | Yes |
| Auth method | HTTP Basic Auth (username = Gorgias account email, password = API token generated in Settings → REST API) |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | Not available on any plan |
Authentication
Auth method: HTTP Basic Auth (username = Gorgias account email, password = API token generated in Settings → REST API)
Setup steps
- Log in to your Gorgias account as an Admin.
- Navigate to Settings → REST API.
- Click 'Create API Key' and copy the generated token.
- Use the account owner email as the HTTP Basic Auth username and the API token as the password.
- Base64-encode 'email:token' and pass it in the Authorization header: 'Authorization: Basic
'.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| read:users | Read agent/user records | GET /users, GET /users/{id} |
| write:users | Create, update, and delete agent/user records | POST /users, PUT /users/{id}, DELETE /users/{id} |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | integer | Unique agent ID | auto-assigned | immutable | |
| string | Agent email address (login) | required | optional | Must be unique within the account | |
| name | string | Full display name | required | optional | |
| firstname | string | First name | optional | optional | |
| lastname | string | Last name | optional | optional | |
| role | object | Agent role (e.g., admin, agent, observer) | optional | optional | Nested object with id and name |
| active | boolean | Whether the agent account is active | optional (default true) | optional | Set false to deactivate without deleting |
| bio | string | Agent bio/description | optional | optional | |
| avatar_url | string | URL of agent avatar image | optional | optional | |
| language | string | Preferred language code (e.g., 'en') | optional | optional | |
| timezone | string | Agent timezone (IANA format) | optional | optional | |
| created_datetime | string (ISO 8601) | Timestamp of account creation | auto-assigned | immutable | |
| updated_datetime | string (ISO 8601) | Timestamp of last update | auto-assigned | auto-updated | |
| meta | object | Arbitrary key-value metadata | optional | optional |
Core endpoints
List users (agents)
- Method: GET
- URL:
https://{account}.gorgias.com/api/users - Watch out for: Returns all agent-type users; does not return end-customer contacts (those are under /customers).
Request example
GET /api/users?limit=30&order_by=created_datetime:asc
Authorization: Basic <base64>
Response example
{
"data": [{"id": 1, "email": "agent@example.com", "name": "Jane Doe", "active": true}],
"meta": {"next_cursor": "abc123", "total_count": 42}
}
Get user by ID
- Method: GET
- URL:
https://{account}.gorgias.com/api/users/{id} - Watch out for: Returns 404 if the user ID does not exist or belongs to a different account.
Request example
GET /api/users/42
Authorization: Basic <base64>
Response example
{
"id": 42,
"email": "agent@example.com",
"name": "Jane Doe",
"role": {"id": 1, "name": "agent"},
"active": true
}
Create user (invite agent)
- Method: POST
- URL:
https://{account}.gorgias.com/api/users - Watch out for: Creating a user sends an invitation email. The agent must accept the invite before they can log in. Seat limits apply per plan.
Request example
POST /api/users
Content-Type: application/json
{"email":"newagent@example.com","name":"New Agent","role":{"id":2}}
Response example
{
"id": 99,
"email": "newagent@example.com",
"name": "New Agent",
"active": true,
"created_datetime": "2024-01-15T10:00:00Z"
}
Update user
- Method: PUT
- URL:
https://{account}.gorgias.com/api/users/{id} - Watch out for: PUT replaces the full resource; omitting optional fields may reset them. Use with care.
Request example
PUT /api/users/42
Content-Type: application/json
{"name":"Jane Smith","role":{"id":1},"active":true}
Response example
{
"id": 42,
"email": "agent@example.com",
"name": "Jane Smith",
"active": true,
"updated_datetime": "2024-06-01T12:00:00Z"
}
Deactivate / delete user
- Method: DELETE
- URL:
https://{account}.gorgias.com/api/users/{id} - Watch out for: Deleting an agent is irreversible. Consider setting active=false via PUT to deactivate without data loss.
Request example
DELETE /api/users/42
Authorization: Basic <base64>
Response example
HTTP 204 No Content
List roles
- Method: GET
- URL:
https://{account}.gorgias.com/api/roles - Watch out for: Role IDs are account-specific; retrieve them before assigning roles during user creation.
Request example
GET /api/roles
Authorization: Basic <base64>
Response example
{
"data": [
{"id": 1, "name": "admin"},
{"id": 2, "name": "agent"},
{"id": 3, "name": "observer"}
]
}
Rate limits, pagination, and events
- Rate limits: Gorgias enforces per-account rate limits. Limits vary by plan; responses include rate-limit headers. When the limit is exceeded, the API returns HTTP 429.
- Rate-limit headers: Yes
- Retry-After header: Yes
- Rate-limit notes: Headers returned: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After. Implement exponential back-off on 429 responses.
- Pagination method: cursor
- Default page size: 30
- Max page size: 100
- Pagination pointer: cursor (also supports limit and order_by)
| Plan | Limit | Concurrent |
|---|---|---|
| Starter / Basic | 2 requests/second | 0 |
| Pro / Advanced | 10 requests/second | 0 |
| Enterprise | Custom / higher limits negotiated | 0 |
- Webhooks available: Yes
- Webhook notes: Gorgias supports webhooks for ticket and customer events, but does not expose dedicated user/agent lifecycle webhook events (e.g., agent created, deactivated). Webhooks are configured in Settings → Integrations → HTTP.
- Alternative event strategy: Poll GET /api/users on a schedule to detect agent changes, as no agent-lifecycle webhook events are available.
- Webhook events: ticket-created, ticket-updated, ticket-message-created, customer-created, customer-updated
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: Not available on any plan
- Endpoint: Not documented
Limitations:
- Gorgias does not offer SCIM 2.0 provisioning as of the policy date.
- SSO via Google and Microsoft is available on all plans; custom SAML SSO is available on higher-tier plans.
- Agent provisioning must be done via the REST API or manually through the UI.
Common scenarios
Three provisioning scenarios cover the primary lifecycle operations. To provision a new agent, call GET /api/roles first to retrieve the account-specific role ID - role IDs are not portable across accounts and must be looked up dynamically.
Then POST /api/users with email, name, and role. id; this triggers an invitation email immediately, and the agent seat is consumed against plan limits at creation time, not at acceptance.
The agent cannot authenticate until they accept the invite, which is a caveat for any workflow that assumes immediate access. To deprovision a departing agent, resolve their ID via `GET /api/users?
email={email}, then prefer PUT /api/users/{id}withactive=falseoverDELETE` - deletion is irreversible and will orphan any open tickets assigned to that agent.
For role changes, always re-fetch role IDs from GET /api/roles before issuing the PUT; hardcoding role IDs across environments will cause silent misassignment.
Pagination on list endpoints uses cursor-based traversal with a default page size of 30 and a maximum of 100; use the cursor, limit, and order_by parameters accordingly.
Provision a new agent from an IdP event
- Receive new-hire event from HR system or IdP webhook.
- GET /api/roles to retrieve the correct role ID for the new agent's team.
- POST /api/users with email, name, and role.id to create the agent and trigger invitation email.
- Store the returned user id in your directory for future updates or deprovisioning.
Watch out for: The agent cannot log in until they accept the invitation email. Plan seat limits may cause a 422 error if the account is at capacity.
Deprovision a departing agent
- Receive offboarding event from HR system.
- GET /api/users?email={email} to resolve the Gorgias user ID.
- PUT /api/users/{id} with active=false to immediately disable access without deleting history.
- Optionally DELETE /api/users/{id} if permanent removal is required and ticket reassignment has been completed.
Watch out for: Deleting an agent is irreversible and may orphan open tickets assigned to them. Deactivation (active=false) is the safer default.
Sync agent role changes
- Detect role change in source system (e.g., promotion to team lead).
- GET /api/roles to map the new role name to its Gorgias role ID.
- PUT /api/users/{id} with the updated role object.
- Verify the response reflects the new role before closing the sync task.
Watch out for: Role IDs are not stable across accounts; always look them up dynamically rather than hardcoding them.
Why building this yourself is a trap
The most significant integration caveat is the absence of agent-lifecycle webhooks. Gorgias webhooks cover ticket and customer events only - there are no agent.created, agent.deactivated, or agent.updated events. Any identity graph that needs to stay current with Gorgias agent state must poll GET /api/users on a schedule and diff against its own records.
This polling requirement, combined with the 2 req/s rate limit on lower-tier plans, means sync frequency is constrained for accounts not on Pro or above. A second trap is the PUT semantics: the endpoint performs a full resource replacement, not a partial update.
Omitting optional fields in a PUT body may silently reset them to null or default values - always fetch the current object first and merge before writing back.
Finally, because Gorgias has no SCIM support, any IdP-driven deprovisioning workflow (Okta lifecycle, Azure AD, etc.) requires a custom middleware layer to translate IdP events into REST API calls; there is no native connector path.
Automate Gorgias workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.