Skip to content

API reference
every endpoint, explained

Parameters, request examples and responses for every v3 resource, made from the OpenAPI spec.

Base URLhttps://gorest.co.in/public/v3

This is v3, the current version. The v2 reference or the Swagger UI.

Change stream

Your own changes as they happen, as Server-Sent Events. Read it with fetch or curl -N and your token, or with a browser EventSource and a single use ticket from POST /stream/tickets.

Stream your changes

GET/public/v3/stream/changes

Every create, update and delete in your own v3 data, as Server-Sent Events (text/event-stream), within about a second of the commit. Sample rows never change, so they send nothing. Each event has an id, an event name and one data line of JSON: • ready: the stream is open. Read the data you show now; every change from here on comes as an event. • change: one row was created, updated or deleted. data is a ChangeEvent; read the row at href for its new state. • reset: your data changed as a whole (a reset of your data) or the stream lost its place. Read the data you show again. A comment line : heartbeat comes every 25 seconds. The stream ends after 30 minutes, at the token's end, when the token is revoked, or when the server restarts; connect again after retry milliseconds and send the last id you got as Last-Event-ID. Within 5 minutes you get the events you missed, else reset. An event may come twice after a reconnect; drop one you have seen by its id. At most 3 streams per token and 10 per account on each server. A browser EventSource cannot send a header: get a ticket from POST /stream/tickets and open ?ticket=<ticket>, with &last-event-id=<id> to resume. A ticket works once, also when the connect is refused (a 429, for one), so get a new one before every connect. Needs a token with stream:read.

Parameters

Last-Event-IDheader, stringoptional
The id of the last event you got, to resume.
last-event-idquery, stringoptional
The same as the Last-Event-ID header, for EventSource with a ticket; the header wins when both come.
curl "https://gorest.co.in/public/v3/stream/changes" \
  -H "Authorization: Bearer YOUR_TOKEN"
Response 200
id: 019a3c4e-7b10-7d2a-9c4e-2f1b6a8d0e55
event: change
data: {"resource":"posts","action":"updated","id":"019a3c4e-1111-7d2a-9c4e-2f1b6a8d0e55","version":2,"href":"/public/v3/posts/019a3c4e-1111-7d2a-9c4e-2f1b6a8d0e55"}

Get a stream ticket

POST/public/v3/stream/tickets

A ticket for one GET /stream/changes?ticket=<ticket>, for a browser EventSource, which cannot send the token in a header. It works once, within 60 seconds, and only on the stream; the stream then checks the token that made it, as for a Bearer call. Never put your API token in a URL; a ticket is made to go there. Needs a token with stream:read.

curl -X POST "https://gorest.co.in/public/v3/stream/tickets" \
  -H "Authorization: Bearer YOUR_TOKEN"
Response 201
{
  "ticket": "string",
  "expires_at": "2026-10-31T09:30:00Z"
}

Authentication

Most reads need no token: you see the read only sample data. With a token you also see your own rows. Writes, and the access tokens, my data and change stream calls, need a token with the scope the call names, such as users:write. Make a token on the tokens page after you log in.

Authorization: Bearer YOUR_TOKEN
The only way to send a token in v3. A token never goes in the URL.

No token or a wrong one gives 401 with WWW-Authenticate. A token without the scope gives 403 with error="insufficient_scope". Sample rows (read_only: true) cannot be changed.

Make a token

Pagination

A list answers {"data": [...], "meta": {...}}, 25 items by default. Set page[size] from 1 to 100. For the next page send page[after] with meta.next_cursor; the same link is in the Link header.

meta.has_more
true when there is a next page.
meta.next_cursor
Send it as page[after] for the next page; null on the last one.
meta.total
Only with page[count]=true, or with page[number].
page[number]
Offset paging from 1 to 10,000, in place of page[after].
Link
rel="next", "prev", "first" and, for offset paging, "last" (RFC 8288).

Rate limits

Every answer carries the IETF rate limit fields. A token has its own limit, 300 calls a minute by default (1 to 600, set on the tokens page). With no token, an IP gets 120 calls a minute. Past the limit you get 429 with Retry-After.

RateLimit-Policy
The limit and its window, for example "token";q=300;w=60.
RateLimit
Calls left and the seconds until the window resets.
Retry-After
On a 429: the seconds to wait.

Errors and status codes

200 OK
The item or the list is in the body.
201 Created
The new item is in the body, and Location has its URL.
204 No Content
A delete worked. The body is empty.
304 Not Modified
Your copy (If-None-Match with the ETag) is still good.
400 Bad Request
A parameter is wrong, unknown or out of range.
401 Unauthorized
No token, or it is wrong, expired or revoked.
403 Forbidden
The token lacks the scope, or the row is sample data.
404 Not Found
No such item, or you cannot see it.
409 Conflict
A duplicate, or the same Idempotency-Key is busy.
412 Precondition Failed
If-Match did not match: someone changed the item.
422 Unprocessable
A field failed a check. errors has a pointer and a code for each.
429 Too Many Requests
The rate limit is used up; wait Retry-After seconds.
500 Server Error
A fault on our side. Send the request_id when you report it.
A 422 body 422Every error code
{
  "type": "https://www.gorest.co.in/docs/api/errors#validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "validation_failed",
  "detail": "Some fields are not valid.",
  "instance": "/public/v3/users",
  "request_id": "0190a8e4-0000-7000-8000-0000000000aa",
  "errors": [
    { "pointer": "/email", "code": "taken", "detail": "has already been taken" }
  ]
}

Format and testing

/http/status/503
Answers with that status, with the headers a real one carries. Any code from 200 to 599.
/http/delay/1500
Waits that many milliseconds, up to 10,000, then answers.
ETag and If-Match
Send If-Match on PATCH or DELETE so you never overwrite a newer change (412 if it changed).
Idempotency-Key
A header on POST that makes a retry safe: the same answer for 24 hours.
fields, include, sort
fields[users]=id,name returns fewer fields; include=user embeds the related item; sort=-created_at orders a list.

Want to try a call now? Open the REST console.