links: [[]] --- # Google Style A response can have only one type success or error A success response returns data object ```js { "data": { //... some data } } ``` A error response will returns error object ```js { "error": { //... some error data } } ``` # JSend **Success:** ```js { "status": "success", "data": { /* Application-specific data would go here. */ }, "message": null /* Or optional success message */ } ``` **Error:** ```js { "status": "error", "data": null, /* or optional error payload */ "message": "Error xyz has occurred" } ``` ## Schema v1 #### Common Scenarios **Success:** ```json { "status": "success", "data": { // Requested Resource }, "error": null, "links": {}, // optional HATEOAS-lite "meta": { "request_id": "req_123", "schema_version": "1.0", "generated_at": "2025-08-26T09:05:00Z", "trace_id": "trace_abc", // optional "span_id": "span_xyz", // optional "locale": "en-IN", // reserved for future i18n "idempotency_key": "..." // echo when provided } } ``` **Error:** ```json { "status": "error", "data": null, "error": { "type": "https://errors.example.com/validation/invalid-argument", "title": "Validation failed", "status": 422, "detail": "One or more fields are invalid.", "instance": "req_123", "errors": [ { "path": "email", "reason": "INVALID_FORMAT", "message": "Must be a valid email" }, { "path": "password", "reason": "TOO_SHORT", "min": 12 } ] }, "meta": { "request_id": "req_123", "schema_version": "1.0", "generated_at": "2025-08-26T09:05:00Z", "trace_id": "trace_abc", // optional "span_id": "span_xyz", // optional "locale": "en-IN", // reserved for future i18n "idempotency_key": "..." // echo when provided } } ``` #### Pagination **Cursor** ```json { "ok": true, "code": "USERS_LISTED", "data": { "items": [{ "id": "usr_1" }, { "id": "usr_2" }], "page": { "mode": "cursor", "cursor": "base64blob", // the cursor you used "next_cursor": "base64blob2", "size": 50 } }, "links": { "self": "/v1/users?cursor=base64blob&size=50", "next": "/v1/users?cursor=base64blob2&size=50" }, "meta": { "request_id": "req_123", "schema_version": "1.0", "generated_at": "..." } } ``` **Offset** ```json { "ok": true, "code": "USERS_LISTED", "data": { "items": [{ "id": "usr_1" }, { "id": "usr_2" }], "page": { "mode": "offset", "offset": 200, "limit": 50, "has_more": true } }, "links": { "self": "/v1/users?offset=200&limit=50", "next": "/v1/users?offset=250&limit=50" }, "meta": { "request_id": "req_456", "schema_version": "1.0", "generated_at": "..." } } ``` **Mutations (Create, Update, Delete)** ```json { "ok": true, "code": "USER_CREATED", "data": { "id": "usr_123", "status": "active" }, "links": { "self": "/v1/users/usr_123" }, "meta": { "request_id": "req_999", "schema_version": "1.0", "generated_at": "2025-08-26T09:05:00Z", "etag": "W/\"usr_123-abc\"", "idempotency_key": "8e0e5f4e-..." } } ``` **Bulk Operations** ```json { "ok": true, "code": "BULK_RESULT", "data": { "successes": [ { "index": 0, "id": "usr_1" }, { "index": 2, "id": "usr_3" } ], "failures": [ { "index": 1, "error": { "type": "https://errors.example.com/validation/unique", "title": "Validation failed", "status": 422, "code": "VALIDATION_FAILED", "detail": "Email is already taken", "errors": [{ "path": "email", "reason": "UNIQUE" }] } } ] }, "meta": { "request_id": "req_bulk_1", "schema_version": "1.0", "generated_at": "..." } } ``` **Long Running Operations** Start: ```json { "ok": true, "code": "OPERATION_ACCEPTED", "data": { "name": "operations/op_789", "done": false, "metadata": { "kind": "user.import", "submitted_at": "2025-08-26T09:05:00Z", "progress": { "completed": 0, "total": 1000 } } }, "meta": { "request_id": "req_lro_1", "schema_version": "1.0", "generated_at": "..." } } ``` Poll --> Success ```json { "ok": true, "code": "OPERATION_SUCCEEDED", "data": { "name": "operations/op_789", "done": true, "response": { "imported": 995, "skipped": 5 } }, "meta": { "request_id": "req_lro_2", "schema_version": "1.0", "generated_at": "..." } } ``` Poll --> Error ```json { "ok": false, "code": "OPERATION_FAILED", "error": { "type": "https://errors.example.com/job/failed", "title": "Job failed", "status": 500, "detail": "Worker crashed on shard 3" }, "data": null, "meta": { "request_id": "req_lro_3", "schema_version": "1.0", "generated_at": "..." } } ``` **Concurrency, Idempotency, Rate Limits** ### Concurrency (ETags) - Write endpoints accept `If-Match: <etag>`; on mismatch: ```json { "ok": false, "code": "PRECONDITION_FAILED", "error": { "type": "https://errors.example.com/precondition/etag-mismatch", "title": "Precondition failed", "status": 412, "detail": "Resource has changed; refresh and retry with the latest ETag" }, "meta": { "request_id": "req_412", "schema_version": "1.0", "generated_at": "..." } } ``` --- tags: #backend, #rest-api sources: - [Google Json api response guide](https://google.github.io/styleguide/jsoncstyleguide.xml#Top-Level_Reserved_Property_Names) - [Standard for json Api format](https://stackoverflow.com/questions/12806386/is-there-any-standard-for-json-api-response-format)