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/v3This is v3, the current version. The v2 todos reference or the Swagger UI.
Tasks
To do items, each optionally given to a user.
The task object
- idstring (uuid)
- user_idstring, or null (uuid)
- Who the task is for; null when nobody.
- titlestring
- descriptionstring
- statustodo | in_progress | done
- prioritylow | medium | high | urgent
- due_onstring, or null (date)
- read_onlyboolean
- True for sample data (the seed); it cannot be changed.
- created_atstring (date-time)
- updated_atstring (date-time)
- userNullableUser
- The user, or null when there is none or you cannot see it.
{
"id": "0190a8e4-0000-7000-8000-000000000001",
"user_id": "0190a8e4-0000-7000-8000-000000000001",
"title": "Add paging to the orders list",
"description": "Write the tests first.",
"status": "todo",
"priority": "low",
"due_on": "2026-11-15",
"read_only": false,
"created_at": "2026-10-31T09:30:00Z",
"updated_at": "2026-10-31T09:30:00Z"
}List tasks
GET/public/v3/tasksA token is optional (with tasks:read): with one you also see your own rows.
Parameters
- page[size]query, integeroptional
- Items on one page.
- page[after]query, stringoptional
- The cursor of the next page, from
meta.next_cursoror theLinkheader. Treat it as opaque; it works only with the same query. - page[number]query, integeroptional
- Offset paging, 1 based, at most 10,000. Cannot be sent with
page[after]. Pages can shift while you write. - page[count]query, booleanoptional
trueaddsmeta.totalto a cursor page (it costs a count).- searchquery, stringoptional
- Case-insensitive text search over the resource's text fields.
- filterquery, objectoptional
filter[user_id]=(one user),filter[status]=todo,in_progress,doneandfilter[priority]=low,medium,high,urgent(any of). An id you cannot see gives an empty list.- sortquery, created_at | -created_at | title | -titleoptional
- One field; a leading
-sorts descending. Default-created_at. - fieldsquery, objectoptional
fields[tasks]=id,titlereturns only those fields; included items are added whole.- includequery, stringoptional
- Adds related items to each item, one level deep:
user. Comma separated. - If-None-Matchheader, stringoptional
- An ETag from an earlier answer; an unchanged item answers 304 with no body.
curl -g "https://gorest.co.in/public/v3/tasks?page[size]=10"
{
"data": [
{
"id": "0190a8e4-0000-7000-8000-000000000001",
"user_id": "0190a8e4-0000-7000-8000-000000000001",
"title": "Add paging to the orders list",
"description": "Write the tests first.",
"status": "todo",
"priority": "low",
"due_on": "2026-11-15",
"read_only": false,
"created_at": "2026-10-31T09:30:00Z",
"updated_at": "2026-10-31T09:30:00Z"
}
],
"meta": {
"has_more": false,
"next_cursor": null,
"total": null
}
}Create a task
POST/public/v3/tasksNeeds a token with tasks:write.
Parameters
- Idempotency-Keyheader, stringoptional
- A unique key (a UUID is fine) that makes a POST safe to retry for 24 hours. A retry with the same key, path and body gets the first answer again with
Idempotent-Replayed: trueand creates nothing; a retry while the first is still running gets 409conflictwithRetry-After: 1. The same key with another request gets 422idempotency_key_mismatch. Only a 2xx answer is kept, so after an error the retry runs again. An answer over 64 KiB, or one that holds a new token's value, is not kept: its retry gets 409conflictwith theLocationof what the first request made. - user_idbody, string, or null (uuid)optional
- A user you can see.
- titlebody, stringrequired
- Not blank; spaces at the ends are dropped.
- descriptionbody, stringoptional
- statusbody, todo | in_progress | doneoptional
- prioritybody, low | medium | high | urgentoptional
- due_onbody, string, or null (date)optional
curl -X POST "https://gorest.co.in/public/v3/tasks" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Add paging to the orders list"}'{
"id": "0190a8e4-0000-7000-8000-000000000001",
"user_id": "0190a8e4-0000-7000-8000-000000000001",
"title": "Add paging to the orders list",
"description": "Write the tests first.",
"status": "todo",
"priority": "low",
"due_on": "2026-11-15",
"read_only": false,
"created_at": "2026-10-31T09:30:00Z",
"updated_at": "2026-10-31T09:30:00Z"
}Get a task
GET/public/v3/tasks/:idA token is optional (with tasks:read): with one you also see your own rows.
Parameters
- idpath, string (uuid)required
- A UUID.
- fieldsquery, objectoptional
fields[tasks]=id,titlereturns only those fields; included items are added whole.- includequery, stringoptional
- Adds related items to each item, one level deep:
user. Comma separated. - If-None-Matchheader, stringoptional
- An ETag from an earlier answer; an unchanged item answers 304 with no body.
curl "https://gorest.co.in/public/v3/tasks/0190a8e4-0000-7000-8000-000000000001"
{
"id": "0190a8e4-0000-7000-8000-000000000001",
"user_id": "0190a8e4-0000-7000-8000-000000000001",
"title": "Add paging to the orders list",
"description": "Write the tests first.",
"status": "todo",
"priority": "low",
"due_on": "2026-11-15",
"read_only": false,
"created_at": "2026-10-31T09:30:00Z",
"updated_at": "2026-10-31T09:30:00Z"
}Change a task (JSON Merge Patch)
PATCH/public/v3/tasks/:idNeeds a token with tasks:write.
Parameters
- idpath, string (uuid)required
- A UUID.
- If-Matchheader, stringoptional
- The strong ETag the change is based on, from a read without
includeor from the last write; when the item changed since, the answer is 412. A weak ETag never matches. - Preferheader, return=minimal | return=representationoptional
return=minimalfor an answer with no body,return=representation(the default) for the full item (RFC 7240).- user_idbody, string, or null (uuid)optional
- A user you can see, or null for nobody.
- titlebody, stringoptional
- Not blank; spaces at the ends are dropped.
- descriptionbody, stringoptional
- statusbody, todo | in_progress | doneoptional
- prioritybody, low | medium | high | urgentoptional
- due_onbody, string, or null (date)optional
- A date, or null for none.
curl -X PATCH "https://gorest.co.in/public/v3/tasks/0190a8e4-0000-7000-8000-000000000001" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"user_id":"0190a8e4-0000-7000-8000-000000000001"}'{
"id": "0190a8e4-0000-7000-8000-000000000001",
"user_id": "0190a8e4-0000-7000-8000-000000000001",
"title": "Add paging to the orders list",
"description": "Write the tests first.",
"status": "todo",
"priority": "low",
"due_on": "2026-11-15",
"read_only": false,
"created_at": "2026-10-31T09:30:00Z",
"updated_at": "2026-10-31T09:30:00Z"
}Delete a task
DELETE/public/v3/tasks/:idNeeds a token with tasks:write.
Parameters
- idpath, string (uuid)required
- A UUID.
- If-Matchheader, stringoptional
- The strong ETag the change is based on, from a read without
includeor from the last write; when the item changed since, the answer is 412. A weak ETag never matches.
curl -X DELETE "https://gorest.co.in/public/v3/tasks/0190a8e4-0000-7000-8000-000000000001" \ -H "Authorization: Bearer YOUR_TOKEN"
(empty body)
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.
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.
{
"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.