Skip to content

👥 Fake Users, Posts, Comments & Todos API

Users with Khmer and English names, posts, comments, todos and quotes for social and list screens.

Need a feed, a profile page or a to-do list to practise with? This API has 30 users, many with Khmer names in both scripts (fullNameKm) and Cambodian addresses, plus 100 posts (some written in Khmer), 300 comments, 150 todos and quotes including traditional Khmer proverbs.

Relations work like a real backend: /users/1/posts, /posts/5/comments, /users/3/todos. Every list supports search, filters, sorting, field selection and pagination. Nothing is saved: the response shows what a real API would return, and the data stays the same for everyone.

Base URL https://toolorca.com/api/v1 No key · CORS open · JSON · conventions and limits

Endpoints

GET /api/v1/users #

List users.

Parameter In Type Description
q query string Full-text search in the main text fields.
sortBy query string Field to sort by, e.g. price or rating.rate.
order query string asc (default) or desc.
select query string Comma-separated fields to return, e.g. title,price (id is always included).
limit query integer Items per page (default 30, max 100). 0 returns the maximum.
skip query integer Items to skip, for offset pagination.
page query integer 1-based page number; used when skip is not given.
gender query string female or male.
role query string admin, moderator or user.
city / country query string City name or two-letter country code, e.g. country=KH.
curl 'https://toolorca.com/api/v1/users?country=KH&limit=3&select=fullName,fullNameKm,avatar'
GET /users?country=KH&limit=3&select=fullName,fullNameKm,avatar
Example response
{
  "data": [
    {
      "id": 1,
      "fullName": "Chan Sokha",
      "fullNameKm": "ចាន់ សុខា",
      "avatar": "https://toolorca.com/api/v1/images/placeholder/200x200.png?text=SC&bg=0f6fde&fg=ffffff"
    },
    {
      "id": 2,
      "fullName": "Sok Dara",
      "fullNameKm": "សុខ ដារ៉ា",
      "avatar": "https://toolorca.com/api/v1/images/placeholder/200x200.png?text=DS&bg=7c3aed&fg=ffffff"
    },
    {
      "id": 3,
      "fullName": "Kim Sophea",
      "fullNameKm": "គីម សុភា",
      "avatar": "https://toolorca.com/api/v1/images/placeholder/200x200.png?text=SK&bg=db2777&fg=ffffff"
    }
  ],
  "meta": {
    "total": 19,
    "limit": 3,
    "skip": 0,
    "page": 1,
    "pages": 7
  }
}

GET /api/v1/users/{id} #

One user with address, company and avatar.

Parameter In Type Description
id required path integer The user id.
curl 'https://toolorca.com/api/v1/users/1'
GET /users/1
Example response
{
  "id": 1,
  "firstName": "Sokha",
  "lastName": "Chan",
  "fullName": "Chan Sokha",
  "firstNameKm": "សុខា",
  "lastNameKm": "ចាន់",
  "fullNameKm": "ចាន់ សុខា",
  "username": "sokha.chan",
  "email": "sokha.chan@example.com",
  "phone": "+855 17 915 876",
  "gender": "female",
  "birthDate": "1984-12-24",
  "age": 41,
  "role": "admin",
  "avatar": "https://toolorca.com/api/v1/images/placeholder/200x200.png?text=SC&bg=0f6fde&fg=ffffff",
  "address": {
    "street": "No. 13, Street 2004",
    "city": "Phnom Penh",
    "cityKm": "ភ្នំពេញ",
    "postalCode": "12072",
    "country": "Cambodia",
    "countryCode": "KH",
    "coordinates": {
      "lat": 11.5344,
      "lng": 104.9561
    }
  },
  "company": {
    "name": "Sabay Learning Center",
    "department": "Marketing",
    "title": "Mobile Developer"
  },
  "language": "km",
  "createdAt": "2024-02-22T00:00:00Z"
}

GET /api/v1/users/{id}/posts #

Posts written by a user. Also /users/{id}/todos and /users/{id}/carts.

Parameter In Type Description
id required path integer The user id.
limit query integer Items per page (default 30, max 100). 0 returns the maximum.
skip query integer Items to skip, for offset pagination.
page query integer 1-based page number; used when skip is not given.
curl 'https://toolorca.com/api/v1/users/2/posts?limit=2'
GET /users/2/posts?limit=2
Example response
{
  "data": [
    {
      "id": 30,
      "userId": 2,
      "title": "ពិធីបុណ្យអុំទូកនៅភ្នំពេញ",
      "body": "ថ្ងៃនេះខ្ញុំចង់ចែករំលែកបទពិសោធន៍ខ្លះៗជាមួយអ្នកទាំងអស់គ្នា។ មនុស្សរាប់ពាន់នាក់មកមើលការប្រណាំងទូកនៅមាត់ទន្លេ។ ខ្ញុំសង្ឃឹមថាអត្ថបទនេះមានប្រយោជន៍សម្រាប់អ្នក។",
      "lang": "km",
      "tags": [
        "cambodia",
        "festival"
      ],
      "reactions": {
        "likes": 1444,
        "dislikes": 6
      },
      "views": 3715,
      "createdAt": "2025-11-28T08:10:58Z"
    },
    {
      "id": 67,
      "userId": 2,
      "title": "Pagination done right (part 6)",
      "body": "Never load thousands of rows at once. Show a loading indicator at the end of the list. Tell the user when there is nothing more to load.",
      "lang": "en",
      "tags": [
        "api",
        "programming"
      ],
      "reactions": {
        "likes": 655,
        "dislikes": 40
      },
      "views": 4011,
      "createdAt": "2025-11-22T17:50:14Z"
    }
  ],
  "meta": {
    "total": 4,
    "limit": 2,
    "skip": 0,
    "page": 1,
    "pages": 2
  }
}

GET /api/v1/posts #

List posts.

Parameter In Type Description
q query string Full-text search in the main text fields.
sortBy query string Field to sort by, e.g. price or rating.rate.
order query string asc (default) or desc.
select query string Comma-separated fields to return, e.g. title,price (id is always included).
limit query integer Items per page (default 30, max 100). 0 returns the maximum.
skip query integer Items to skip, for offset pagination.
page query integer 1-based page number; used when skip is not given.
userId query integer Posts by this user.
tag query string Posts with this tag, e.g. flutter.
lang query string en or km.
curl 'https://toolorca.com/api/v1/posts?lang=km&limit=2'
GET /posts?lang=km&limit=2
Example response
{
  "data": [
    {
      "id": 5,
      "userId": 12,
      "title": "ការរៀនសរសេរកម្មវិធីសម្រាប់អ្នកចាប់ផ្ដើម",
      "body": "ថ្ងៃនេះខ្ញុំចង់ចែករំលែកបទពិសោធន៍ខ្លះៗជាមួយអ្នកទាំងអស់គ្នា។ ចាប់ផ្ដើមពីមេរៀនងាយៗ ហើយអនុវត្តរាល់ថ្ងៃ។ ខ្ញុំសង្ឃឹមថាអត្ថបទនេះមានប្រយោជន៍សម្រាប់អ្នក។",
      "lang": "km",
      "tags": [
        "programming",
        "study"
      ],
      "reactions": {
        "likes": 851,
        "dislikes": 11
      },
      "views": 8395,
      "createdAt": "2025-04-03T11:37:21Z"
    },
    {
      "id": 10,
      "userId": 10,
      "title": "ដំណើរកម្សាន្តទៅកំពត និងកែប",
      "body": "ថ្ងៃនេះខ្ញុំចង់ចែករំលែកបទពិសោធន៍ខ្លះៗជាមួយអ្នកទាំងអស់គ្នា។ ខ្យល់សមុទ្រ និងម្ហូបក្ដាមកែប ធ្វើឲ្យដំណើរនេះពិសេសណាស់។ ខ្ញុំសង្ឃឹមថាអត្ថបទនេះមានប្រយោជន៍សម្រាប់អ្នក។",
      "lang": "km",
      "tags": [
        "travel",
        "cambodia"
      ],
      "reactions": {
        "likes": 1051,
        "dislikes": 50
      },
      "views": 7420,
      "createdAt": "2025-08-14T10:49:59Z"
    }
  ],
  "meta": {
    "total": 20,
    "limit": 2,
    "skip": 0,
    "page": 1,
    "pages": 10
  }
}

GET /api/v1/posts/{id} #

One post.

Parameter In Type Description
id required path integer The post id.
curl 'https://toolorca.com/api/v1/posts/1'
GET /posts/1
Example response
{
  "id": 1,
  "userId": 19,
  "title": "Getting started with REST APIs",
  "body": "Start with GET requests, then try POST and PUT. A REST API lets your app read and change data over HTTP. Fake APIs are perfect for building screens before the real backend is ready.",
  "lang": "en",
  "tags": [
    "api",
    "programming"
  ],
  "reactions": {
    "likes": 178,
    "dislikes": 42
  },
  "views": 6500,
  "createdAt": "2025-12-20T01:46:16Z"
}

GET /api/v1/posts/{id}/comments #

Comments on a post. The full list is at /comments (filter with postId or userId).

Parameter In Type Description
id required path integer The post id.
limit query integer Items per page (default 30, max 100). 0 returns the maximum.
skip query integer Items to skip, for offset pagination.
page query integer 1-based page number; used when skip is not given.
curl 'https://toolorca.com/api/v1/posts/1/comments'
GET /posts/1/comments
Example response
{
  "data": [
    {
      "id": 1,
      "postId": 1,
      "userId": 26,
      "body": "Thanks, this saved me hours.",
      "likes": 18,
      "createdAt": "2025-12-20T10:46:16Z"
    },
    {
      "id": 101,
      "postId": 1,
      "userId": 22,
      "body": "Bookmarked for later.",
      "likes": 119,
      "createdAt": "2025-12-21T03:46:16Z"
    },
    {
      "id": 201,
      "postId": 1,
      "userId": 21,
      "body": "Great post, thanks for sharing!",
      "likes": 106,
      "createdAt": "2025-12-21T03:46:16Z"
    }
  ],
  "meta": {
    "total": 3,
    "limit": 30,
    "skip": 0,
    "page": 1,
    "pages": 1
  }
}

POST /api/v1/posts #

Create a post. Returns 201 with id 101. Nothing is saved: the response shows what a real API would return, and the data stays the same for everyone.

Parameter In Type Description
title required body string Post title.
body required body string Post text.
userId required body integer Author.
curl -X POST 'https://toolorca.com/api/v1/posts' \
  -H 'Content-Type: application/json' \
  -d '{"title":"សួស្តី Flutter!","body":"My first post from my app.","userId":1}'
POST /posts
Example response (201)
{
  "id": 101,
  "title": "សួស្តី Flutter!",
  "body": "My first post from my app.",
  "userId": 1,
  "createdAt": "2026-11-14T05:15:25Z"
}

GET /api/v1/todos #

List todos.

Parameter In Type Description
q query string Full-text search in the main text fields.
sortBy query string Field to sort by, e.g. price or rating.rate.
order query string asc (default) or desc.
select query string Comma-separated fields to return, e.g. title,price (id is always included).
limit query integer Items per page (default 30, max 100). 0 returns the maximum.
skip query integer Items to skip, for offset pagination.
page query integer 1-based page number; used when skip is not given.
userId query integer Todos of this user.
completed query boolean true or false.
priority query string low, medium or high.
curl 'https://toolorca.com/api/v1/todos?userId=1&limit=3'
GET /todos?userId=1&limit=3
Example response
{
  "data": [
    {
      "id": 1,
      "userId": 1,
      "title": "Review the pull request",
      "completed": false,
      "priority": "high",
      "dueDate": "2026-11-21"
    },
    {
      "id": 31,
      "userId": 1,
      "title": "Reply to customer emails",
      "completed": false,
      "priority": "medium",
      "dueDate": "2026-02-27"
    },
    {
      "id": 61,
      "userId": 1,
      "title": "Prepare slides for the Monday meeting",
      "completed": false,
      "priority": "high",
      "dueDate": "2026-06-11"
    }
  ],
  "meta": {
    "total": 5,
    "limit": 3,
    "skip": 0,
    "page": 1,
    "pages": 2
  }
}

PATCH /api/v1/todos/{id} #

Tick a todo off (or change any field). PUT, POST and DELETE work too. Nothing is saved: the response shows what a real API would return, and the data stays the same for everyone.

Parameter In Type Description
id required path integer The todo id.
completed body boolean New state.
curl -X PATCH 'https://toolorca.com/api/v1/todos/1' \
  -H 'Content-Type: application/json' \
  -d '{"completed":true}'
PATCH /todos/1
Example response
{
  "id": 1,
  "userId": 1,
  "title": "Review the pull request",
  "completed": true,
  "priority": "high",
  "dueDate": "2026-11-21",
  "updatedAt": "2026-11-14T05:15:25Z"
}

GET /api/v1/quotes #

Quotes about learning and programming, and Khmer proverbs with an English meaning (read-only).

Parameter In Type Description
q query string Full-text search in the main text fields.
sortBy query string Field to sort by, e.g. price or rating.rate.
order query string asc (default) or desc.
select query string Comma-separated fields to return, e.g. title,price (id is always included).
limit query integer Items per page (default 30, max 100). 0 returns the maximum.
skip query integer Items to skip, for offset pagination.
page query integer 1-based page number; used when skip is not given.
category query string programming, wisdom, learning, motivation, life or khmer-proverb.
lang query string en or km.
curl 'https://toolorca.com/api/v1/quotes?category=khmer-proverb&limit=2'
GET /quotes?category=khmer-proverb&limit=2
Example response
{
  "data": [
    {
      "id": 21,
      "quote": "ចេះមកពីរៀន មានមកពីរក",
      "translation": "Knowledge comes from learning; wealth comes from working for it.",
      "author": "Khmer proverb",
      "category": "khmer-proverb",
      "lang": "km"
    },
    {
      "id": 22,
      "quote": "ទឹកឡើងត្រីស៊ីស្រមោច ទឹកស្រកស្រមោចស៊ីត្រី",
      "translation": "When the water rises, fish eat ants; when it falls, ants eat fish. Fortunes change, so treat others well.",
      "author": "Khmer proverb",
      "category": "khmer-proverb",
      "lang": "km"
    }
  ],
  "meta": {
    "total": 5,
    "limit": 2,
    "skip": 0,
    "page": 1,
    "pages": 3
  }
}

GET /api/v1/quotes/random #

One random quote (a new one on every call). Accepts category and lang.

Parameter In Type Description
category query string Optional category.
lang query string Optional language.
curl 'https://toolorca.com/api/v1/quotes/random'
GET /quotes/random
Example response
{
  "id": 25,
  "quote": "ឃើញដំរីជុះ កុំជុះតាមដំរី",
  "translation": "When you see the elephant relieve itself, do not try to copy it: do not imitate those far bigger than you.",
  "author": "Khmer proverb",
  "category": "khmer-proverb",
  "lang": "km"
}

The data at a glance

users (30): name in English and, for Cambodian users, Khmer (family name first, as in Cambodia: ចាន់ សុខា); username, email at example.com, phone, gender, birth date, role, PNG avatar with initials, address with coordinates and company. Every user can log in through the Fake Auth API.

posts (100, every fifth one in Khmer) with tags, reactions and views; comments (300, three per post); todos (150, five per user) with priority and due date; quotes (25).

Frequently asked questions

Is this a JSONPlaceholder alternative?

Yes. The routes look familiar (/users, /posts, /comments, /todos), with richer fields, Khmer content and a consistent { data, meta } list format.

Are the people real?

No. Names, emails (example.com), phone numbers, addresses and companies are invented.

Does the data change?

No. Every request returns the same data, and write requests are not saved, so everyone sees the same results.

Can I show Khmer text from the API?

Yes. All responses are UTF-8 JSON. Make sure your app uses a font with Khmer glyphs (most phones have one).

More free APIs