Skip to content

REST Requests And Responses

Examples use the Project resource at http://127.0.0.1:8080. Authentication examples use the default header X-Authorization: Bearer <access-token>.

Where Parameters Come From

HTTP method Input consumed by the REST parameter helpers
POST, PUT, PATCH JSON body for application/json or a +json media type; otherwise form body
GET, DELETE, other methods Query string

Body and query parameters are not merged. Put update identity in the body:

curl -X PATCH http://127.0.0.1:8080/api/project/update \
  -b cookies.txt -c cookies.txt \
  -H "X-Authorization: Bearer $API_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"id":1,"label":"Community garden expansion"}'

A DELETE uses query parameters:

curl -X DELETE 'http://127.0.0.1:8080/api/project/delete?id=1' \
  -b cookies.txt -c cookies.txt \
  -H "X-Authorization: Bearer $API_TOKEN"

For filters, use bracket-encoded query arrays or a JSON array in a JSON body. A JSON string inside a query parameter is not decoded into a filter array. See Filtering. The internal _url rewrite parameter is removed from REST input.

The generic input helper is not a JSON schema validator. Validate required fields, accepted shapes, and limits for custom endpoints. In particular, do not interpret HTTP 200 from an empty save batch as proof that a record was created.

The JSON Envelope

A successful list returns:

{
  "timestamp": "2026-09-29T10:00:00-04:00",
  "status": "OK",
  "code": 200,
  "response": true,
  "view": {
    "data": [
      {"id": 1, "label": "Community garden", "status": "active", "budget": 1200}
    ]
  }
}
Field Meaning
timestamp Server response time, including timezone offset
status HTTP reason phrase
code HTTP status code; also check the actual HTTP status
response Action result, often boolean; may be null or another value
view Action-specific data and metadata
debug Optional development diagnostics when debugging is enabled

view.data is a list for find, an object for find-first, and an exposed saved record for a successful write. The envelope does not use success or a top-level data field. An empty view serializes as []; clients should tolerate it.

Empty And Missing Results

No list matches, HTTP 200:

{
  "timestamp": "2026-09-29T10:00:00-04:00",
  "status": "OK",
  "code": 200,
  "response": true,
  "view": {"data": []}
}

No single-record match, HTTP 404:

{
  "timestamp": "2026-09-29T10:00:00-04:00",
  "status": "Not Found",
  "code": 404,
  "response": null,
  "view": []
}

A row hidden by ownership or soft-delete conditions is also a non-match. Do not assume a 404 proves the database contains no row with that ID.

Validation Errors

Creating a duplicate label in the tutorial returns HTTP 422:

{
  "timestamp": "2026-09-29T10:00:00-04:00",
  "status": "Unprocessable Entity",
  "code": 422,
  "response": false,
  "view": {
    "saved": false,
    "messages": [
      {
        "field": "label",
        "message": "not-unique",
        "type": "Phalcon\\Filter\\Validation\\Validator\\Uniqueness",
        "code": 0,
        "metaData": []
      }
    ]
  }
}

messages[].code is a model message code, not necessarily the HTTP status. Applications may supply translated messages, field lists, metadata, and custom message types. Distinct-field errors use a string message list; custom error controllers may use another shape. Normalize messages in your client instead of assuming every entry is an object.

Status Reference

Status Typical cause
200 Read, successful update/save/delete/restore/reorder, or all-success batch
201 Single successful explicit create
207 Batch contains both saved and failed rows; response is false
304 Conditional cached response, when enabled and validator matches; no body
400 Missing update identity, invalid input, excessive limit, invalid distinct field
401 Rejected authentication token or failed login
403 Disallowed filter/order/relationship/count option, or denied permission
404 Missing/hidden row, unknown route/component, or unavailable update target
405 Your application's method guard rejects the HTTP verb
422 Validation failure or a batch in which every row failed
500 Application/configuration/database failure or unsupported model behavior

Permission forwarding can produce 401, 403, or 404 depending on component registration, roles, and configured error routes. Inspect the status and message; do not promise that all permission failures share one status.

JavaScript Client

This helper deliberately checks both HTTP status and the envelope: HTTP 207 is ok to fetch, but its failed rows still need attention.

async function api(path, {token, ...options} = {}) {
  const headers = new Headers(options.headers);
  if (token) headers.set('X-Authorization', `Bearer ${token}`);
  const response = await fetch(`/api/${path}`, {...options, headers});
  const payload = await response.json();
  if (response.status === 207) return {partial: true, payload};
  if (!response.ok || payload.response === false) {
    throw Object.assign(new Error(payload.status || 'Request failed'), {
      status: response.status,
      messages: payload.view?.messages ?? [],
      payload,
    });
  }
  return {partial: false, payload};
}

const query = new URLSearchParams({order: 'id asc', limit: '20', count: '1'});
query.set('filters[0][field]', 'status');
query.set('filters[0][operator]', '=');
query.set('filters[0][value]', 'active');
const {payload} = await api(`project/find?${query}`);
console.log(payload.view.data, payload.view.count);

Handle network errors separately. Do not use this JSON helper for exports or 304 responses, which have a different body contract. Choose token storage based on your application's browser/XSS threat model; avoid placing bearer credentials in URLs or logs.

Caching And Cross-Origin Clients

Response caching is optional. Configure it deliberately and test identity isolation before enabling it on authenticated endpoints. Debug responses may include sensitive internals; keep APP_DEBUG=false outside local development.

For a frontend on another origin, allow its explicit origin and the configured authorization header in CORS. Cookie-based cross-origin requests also need credentials on both client and server. See Application Security.