{
  "service": "data.placeholder.com mock REST API",
  "version": "v1",
  "description": "Free fake REST API for prototypes, tests and AI agents. Same URL, same bytes, forever. Writes are simulated and never stored.",
  "resources": {
    "users": {
      "count": 10,
      "list": "/api/users",
      "item": "/api/users/1",
      "nested": [
        "/api/users/1/posts",
        "/api/users/1/albums",
        "/api/users/1/todos",
        "/api/users/1/orders"
      ]
    },
    "posts": {
      "count": 100,
      "list": "/api/posts",
      "item": "/api/posts/1",
      "belongsTo": {
        "field": "userId",
        "resource": "users"
      },
      "nested": [
        "/api/posts/1/comments"
      ]
    },
    "comments": {
      "count": 500,
      "list": "/api/comments",
      "item": "/api/comments/1",
      "belongsTo": {
        "field": "postId",
        "resource": "posts"
      }
    },
    "albums": {
      "count": 100,
      "list": "/api/albums",
      "item": "/api/albums/1",
      "belongsTo": {
        "field": "userId",
        "resource": "users"
      },
      "nested": [
        "/api/albums/1/photos"
      ]
    },
    "photos": {
      "count": 5000,
      "list": "/api/photos",
      "item": "/api/photos/1",
      "belongsTo": {
        "field": "albumId",
        "resource": "albums"
      }
    },
    "todos": {
      "count": 200,
      "list": "/api/todos",
      "item": "/api/todos/1",
      "belongsTo": {
        "field": "userId",
        "resource": "users"
      }
    },
    "products": {
      "count": 50,
      "list": "/api/products",
      "item": "/api/products/1"
    },
    "orders": {
      "count": 100,
      "list": "/api/orders",
      "item": "/api/orders/1",
      "belongsTo": {
        "field": "userId",
        "resource": "users"
      }
    }
  },
  "users": {
    "source": "synthetic personas; user N is persona <country>-N",
    "defaultMix": [
      "US",
      "GB",
      "SE",
      "NO"
    ],
    "country": "?country=<code> makes all 10 users come from one country; available: SE, NO, GB, US"
  },
  "query": {
    "<field>=<value>": "filter by field (dot paths like address.city; repeat a key for OR)",
    "<field>_ne|_like|_gte|_lte|_gt|_lt=<value>": "operators (_like is a case-insensitive substring)",
    "q": "case-insensitive full-text search over string values",
    "_sort, _order": "sort, e.g. _sort=title&_order=desc or _sort=-title; comma lists allowed",
    "_page, _limit": "paginate (_limit defaults to 10 with _page); adds a Link header",
    "_start, _end, _limit": "slice",
    "_embed": "include children, e.g. /api/posts?_embed=comments",
    "_expand": "include the parent, e.g. /api/posts?_expand=user",
    "country": "users from one persona country (also applies to _expand=user)"
  },
  "headers": {
    "X-Total-Count": "matching items before pagination (lists)",
    "Link": "first/prev/next/last when _page is used"
  },
  "writes": {
    "POST /api/<resource>": "201, echoes the body with a new id (count + 1); nested POST sets the parent field",
    "PUT /api/<resource>/<id>": "200, the stored object shallow-merged with the body",
    "PATCH /api/<resource>/<id>": "200, the stored object shallow-merged with the body",
    "DELETE /api/<resource>/<id>": "200, {}",
    "notes": "nothing is persisted; bodies must be JSON objects (400 otherwise); responses are no-store"
  },
  "examples": [
    "/api/users",
    "/api/users?country=SE",
    "/api/users/1/posts",
    "/api/posts?userId=1&_sort=title",
    "/api/posts?_page=2&_limit=5",
    "/api/posts/1/comments",
    "/api/posts/1?_embed=comments&_expand=user",
    "/api/comments?q=dolor",
    "/api/todos?completed=false&userId=3",
    "/api/albums/1/photos?_limit=3",
    "/api/products?category=home&price_lte=100",
    "/api/orders?status=delivered&_sort=-total"
  ]
}