Echo requests, force status codes, simulate slow networks and get placeholder images.
These endpoints help you check that your HTTP client does what you think. /echo shows exactly what arrived: method, headers, query and body. /status/{code} returns any status so you can test error screens, and /delay/{seconds} answers slowly so you can test loading spinners, timeouts and cancel buttons.
/images/placeholder draws a PNG or SVG of any size with your text and colours: useful for list mock-ups, avatars and image caching tests. Pair them with the REST API Client to try requests in your browser.
const res = await fetch('https://toolorca.com/api/v1/echo?lang=km&page=2', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"name": "Sokha",
"city": "ភ្នំពេញ"
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log(data);
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<void> main() async {
final res = await http.post(
Uri.parse('https://toolorca.com/api/v1/echo?lang=km&page=2'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'name': 'Sokha',
'city': 'ភ្នំពេញ',
}),
);
if (res.statusCode >= 400) throw Exception('HTTP ${res.statusCode}');
final data = jsonDecode(utf8.decode(res.bodyBytes));
print(data);
}
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
// Call from a background thread or coroutine (Dispatchers.IO), never the main thread.
val client = OkHttpClient()
val json = """
{
"name": "Sokha",
"city": "ភ្នំពេញ"
}
""".trimIndent()
val request = Request.Builder()
.url("https://toolorca.com/api/v1/echo?lang=km&page=2")
.post(json.toRequestBody("application/json".toMediaType()))
.build()
client.newCall(request).execute().use { res ->
if (!res.isSuccessful) error("HTTP ${res.code}")
println(res.body?.string())
}
Responds with the status code you ask for (200–599).
3xx codes add a Location header, 401 adds WWW-Authenticate, 429 and 503 add Retry-After. 204 and 304 have no body.
Parameter
In
Type
Description
code required
path
integer
HTTP status code, e.g. 404 or 500.
curl 'https://toolorca.com/api/v1/status/404'
const res = await fetch('https://toolorca.com/api/v1/status/404');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log(data);
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<void> main() async {
final res = await http.get(
Uri.parse('https://toolorca.com/api/v1/status/404'),
);
if (res.statusCode >= 400) throw Exception('HTTP ${res.statusCode}');
final data = jsonDecode(utf8.decode(res.bodyBytes));
print(data);
}
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
// Call from a background thread or coroutine (Dispatchers.IO), never the main thread.
val client = OkHttpClient()
val request = Request.Builder()
.url("https://toolorca.com/api/v1/status/404")
.build()
client.newCall(request).execute().use { res ->
if (!res.isSuccessful) error("HTTP ${res.code}")
println(res.body?.string())
}
import Foundation
var request = URLRequest(url: URL(string: "https://toolorca.com/api/v1/status/404")!)
let (data, response) = try await URLSession.shared.data(for: request)
guard let http = response as? HTTPURLResponse, http.statusCode < 400 else {
throw URLError(.badServerResponse)
}
print(String(decoding: data, as: UTF8.self))
Waits, then answers. Use it to test loading states and timeouts.
Parameter
In
Type
Description
seconds required
path
number
0 to 5, decimals allowed (e.g. 1.5).
curl 'https://toolorca.com/api/v1/delay/2'
const res = await fetch('https://toolorca.com/api/v1/delay/2');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log(data);
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<void> main() async {
final res = await http.get(
Uri.parse('https://toolorca.com/api/v1/delay/2'),
);
if (res.statusCode >= 400) throw Exception('HTTP ${res.statusCode}');
final data = jsonDecode(utf8.decode(res.bodyBytes));
print(data);
}
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
// Call from a background thread or coroutine (Dispatchers.IO), never the main thread.
val client = OkHttpClient()
val request = Request.Builder()
.url("https://toolorca.com/api/v1/delay/2")
.build()
client.newCall(request).execute().use { res ->
if (!res.isSuccessful) error("HTTP ${res.code}")
println(res.body?.string())
}
import Foundation
var request = URLRequest(url: URL(string: "https://toolorca.com/api/v1/delay/2")!)
let (data, response) = try await URLSession.shared.data(for: request)
guard let http = response as? HTTPURLResponse, http.statusCode < 400 else {
throw URLError(.badServerResponse)
}
print(String(decoding: data, as: UTF8.self))
const res = await fetch('https://toolorca.com/api/v1/images/placeholder/600x300.png?text=Hello%20Cambodia&bg=0f6fde&fg=ffffff');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log(data);
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<void> main() async {
final res = await http.get(
Uri.parse('https://toolorca.com/api/v1/images/placeholder/600x300.png?text=Hello%20Cambodia&bg=0f6fde&fg=ffffff'),
);
if (res.statusCode >= 400) throw Exception('HTTP ${res.statusCode}');
final data = jsonDecode(utf8.decode(res.bodyBytes));
print(data);
}
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
// Call from a background thread or coroutine (Dispatchers.IO), never the main thread.
val client = OkHttpClient()
val request = Request.Builder()
.url("https://toolorca.com/api/v1/images/placeholder/600x300.png?text=Hello%20Cambodia&bg=0f6fde&fg=ffffff")
.build()
client.newCall(request).execute().use { res ->
if (!res.isSuccessful) error("HTTP ${res.code}")
println(res.body?.string())
}
import Foundation
var request = URLRequest(url: URL(string: "https://toolorca.com/api/v1/images/placeholder/600x300.png?text=Hello%20Cambodia&bg=0f6fde&fg=ffffff")!)
let (data, response) = try await URLSession.shared.data(for: request)
guard let http = response as? HTTPURLResponse, http.statusCode < 400 else {
throw URLError(.badServerResponse)
}
print(String(decoding: data, as: UTF8.self))
GET /images/placeholder/600x300.png?text=Hello%20Cambodia&bg=…
const res = await fetch('https://toolorca.com/api/v1/images/placeholder/600x300.svg?text=%E1%9E%9F%E1%9E%BD%E1%9E%9F%E1%9F%92%E1%9E%8F%E1%9E%B8&bg=16a34a&fg=ffffff');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log(data);
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<void> main() async {
final res = await http.get(
Uri.parse('https://toolorca.com/api/v1/images/placeholder/600x300.svg?text=%E1%9E%9F%E1%9E%BD%E1%9E%9F%E1%9F%92%E1%9E%8F%E1%9E%B8&bg=16a34a&fg=ffffff'),
);
if (res.statusCode >= 400) throw Exception('HTTP ${res.statusCode}');
final data = jsonDecode(utf8.decode(res.bodyBytes));
print(data);
}
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
// Call from a background thread or coroutine (Dispatchers.IO), never the main thread.
val client = OkHttpClient()
val request = Request.Builder()
.url("https://toolorca.com/api/v1/images/placeholder/600x300.svg?text=%E1%9E%9F%E1%9E%BD%E1%9E%9F%E1%9F%92%E1%9E%8F%E1%9E%B8&bg=16a34a&fg=ffffff")
.build()
client.newCall(request).execute().use { res ->
if (!res.isSuccessful) error("HTTP ${res.code}")
println(res.body?.string())
}
import Foundation
var request = URLRequest(url: URL(string: "https://toolorca.com/api/v1/images/placeholder/600x300.svg?text=%E1%9E%9F%E1%9E%BD%E1%9E%9F%E1%9F%92%E1%9E%8F%E1%9E%B8&bg=16a34a&fg=ffffff")!)
let (data, response) = try await URLSession.shared.data(for: request)
guard let http = response as? HTTPURLResponse, http.statusCode < 400 else {
throw URLError(.badServerResponse)
}
print(String(decoding: data, as: UTF8.self))
GET /images/placeholder/600x300.svg?text=%E1%9E%9F%E1%9E%BD%E…
Example image
Ideas for tests
Point your error handling at /status/500, /status/401 and /status/429 and check each one shows the right message. Set your client timeout to 2 seconds and call /delay/3 to make sure the timeout fires. Send a form with /echo to confirm the content type and encoding your library really uses.
Frequently asked questions
Is there a limit on the delay?
Yes, 5 seconds, so that slow requests do not tie up the server.
Why does my request show extra headers in /echo?
Browsers and HTTP libraries add headers such as User-Agent, Accept and Accept-Encoding. /echo shows them so you can see exactly what was sent.
Can I hotlink the placeholder images?
Yes, in prototypes and tutorials. They are cached for a day and have a generous separate rate limit.
Do these endpoints support CORS?
Yes, every /api/v1 endpoint sends Access-Control-Allow-Origin: * and answers preflight requests.