Log in Sign up
Docs/Utility/Echo

Echo v1.0 1 credit / call

GET|POST /api/v1/echo

Echoes your request back — the hello-world of Ksty.ch, free to try.

100 free/month Test keys supported OpenAPI spec Try it in the console
At a glance
Base path
/api/v1/echo
Methods
GET or POST — parameters are read identically from the query string or a JSON body
Auth
X-Api-Key header (never Authorization: Bearer)
Price
1–2 credits per call, by endpoint · about $0.0010 at 1,000 credits/USD
Free tier
100 credits, refilled every month — drawn down before your paid balance
Test mode
Supported — ksty_test_ keys call this API free of charge
Rate limit
60 calls/minute per key by default, raisable per key

Echo API

The Echo API sends back whatever you send it, wrapped in the metadata the gateway saw while processing your request. It runs no upstream, touches no third party, and always succeeds — which is exactly what makes it the fastest way to prove your integration works end to end before you wire in a real API.

Why an echo endpoint exists

Every call on Ksty.ch passes through the same pipeline — key authentication, scope and region checks, rate limiting, then credit metering — before it reaches a handler. When you are setting up a new client, a failure anywhere in that chain looks identical from the outside: a non-200 response. Echo lets you isolate your half of the problem. If Echo returns 200 with your payload intact, then your key, headers, base URL and request encoding are all correct, and any failure against a real API is about that API's parameters rather than your plumbing.

What comes back

A successful call returns your parsed parameters under echo, alongside the request context the gateway attached:

POST /api/v1/echo
X-Api-Key: ksty_test_...
Content-Type: application/json

{"hello": "world"}
{
  "echo": { "hello": "world" },
  "endpoint": "",
  "mode": "test",
  "request_id": "req_8f21c..."
}
  • echo — your parameters exactly as the gateway parsed them, so you can confirm a GET query string or a POST body decodes the way you expect.
  • endpoint — which sub-endpoint ran (empty for the root, delay for the delay endpoint).
  • modetest for a ksty_test_ key or live for a ksty_live_ key, so you can verify which credential you actually sent.
  • request_id — the stable id for this call; log it and quote it to support.

Test vs live mode

Echo is sandbox-enabled, so a ksty_test_ key calls it for free and the response reports "mode": "test". Swap in a ksty_live_ key and the identical call is metered against your balance and reports "mode": "live". Running the same request under both keys is the simplest way to confirm your production and sandbox credentials are wired to the right environments before you flip a real integration live.

The delay endpoint

echo.delay echoes your payload after pausing for a number of seconds (0–5). Use it to exercise the timeout, backoff and retry behaviour of your client against a slow-but-successful response, without needing a real API that happens to be slow.

The delay endpoint costs 2 credits rather than 1, because it holds a worker for the duration of the pause. Keep seconds small in automated tests so you are not paying — or waiting — more than the scenario needs.

When to use it

  • The first call from a new SDK, language or environment, to confirm auth and encoding.
  • Verifying a key's mode (test vs live) and capturing the request_id format for your logs.
  • Load-testing your own client's timeout and retry paths via echo.delay.

Endpoints

GETPOST /api/v1/echo 1 credit

Echo the request payload and metadata

Parameters
ParameterTypeDescription
message optional string Any payload to echo back
Request
curl -X POST "https://ksty.ch/api/v1/echo" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message":"example"}'
<?php
$ch = curl_init('https://ksty.ch/api/v1/echo');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'X-Api-Key: YOUR_API_KEY',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => '{    "message": "example"}',
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://ksty.ch/api/v1/echo', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "message": "example"
})
});
const data = await response.json();
import requests

response = requests.post(
    'https://ksty.ch/api/v1/echo',
    headers={'X-Api-Key': 'YOUR_API_KEY'},
    json={
    "message": "example"
},
)
data = response.json()
Response 200 OK
{
    "echo": {
        "message": "hello"
    },
    "endpoint": "",
    "mode": "test",
    "request_id": "req_8f21c4a0"
}
Response fields
FieldTypeDescription
echo object Your parameters exactly as the gateway parsed them — query string and JSON body are merged into one map.
endpoint string Which endpoint answered. Empty string for the root endpoint, "delay" for echo.delay.
mode string Whether the key that made the call was live or test — the quickest way to confirm you are using the key you meant to.
request_id string Identifier for this call, also returned in the X-Request-Id header and shown in your usage log.
GETPOST /api/v1/echo.delay 2 credits

Echo after N seconds (max 5) — for testing client timeouts

Holds the response open for a fixed number of seconds before answering, so you can exercise the paths that only appear under latency: client read timeouts, retry logic, circuit breakers, and whether your worker pool copes with a slow upstream.

Values above 5 are clamped to 5 rather than rejected — a timeout test should not fail on a validation error. Note the delay happens after metering, so a call that your client abandons mid-flight has still been charged; that is the honest simulation of a real slow upstream.

Parameters
ParameterTypeDescription
seconds optional integer 0–5 Delay in seconds, 0-5 (higher values are clamped) Defaults to 1
Request
curl -X POST "https://ksty.ch/api/v1/echo.delay" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"seconds":1}'
<?php
$ch = curl_init('https://ksty.ch/api/v1/echo.delay');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'X-Api-Key: YOUR_API_KEY',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => '{    "seconds": 1}',
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://ksty.ch/api/v1/echo.delay', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "seconds": 1
})
});
const data = await response.json();
import requests

response = requests.post(
    'https://ksty.ch/api/v1/echo.delay',
    headers={'X-Api-Key': 'YOUR_API_KEY'},
    json={
    "seconds": 1
},
)
data = response.json()
Response 200 OK
{
    "echo": {
        "seconds": 1
    },
    "delayed": 1
}
Response fields
FieldTypeDescription
echo object Your parameters, echoed back unchanged.
delayed integer Seconds actually waited before answering — the clamped value, so you can see when 9 became 5.

Errors

Errors are JSON with a stable error.code — branch on the code, never on the message. Everything below carries the X-Request-Id of the failed call. Requests rejected by this API are not charged, and a 502 after a charge is refunded automatically.

CodeHTTPCause & what to do
invalid_key platform 401 The X-Api-Key header is missing, malformed, revoked or expired. Send an active key. Repeated bad keys from one address are throttled, so fix the header rather than retrying.
forbidden_scope platform 403 The key is valid but not scoped to this API, or it is a test key on an API without sandbox support. Add this API to the key's scopes on the Keys page, or use a key scoped to all APIs.
insufficient_credits platform 402 The balance cannot cover the call. Top up. Nothing is charged and the request never reaches the API, so no work is half-done.
rate_limited platform 429 The key exceeded its per-minute limit. Back off and retry. The limit is per key, so a second key does not share the budget.
upstream_error platform 502 The API failed unexpectedly after being charged. Safe to retry — credits are refunded automatically whenever this is returned.

Response headers

Every successful call reports its own cost, so you never have to guess what a request spent or reconcile it later.

HeaderMeaning
X-Credits-Charged Credits taken for this call. Zero on test-mode calls and on errors raised before the work started.
X-Credits-Remaining Balance left afterwards, across per-API grants, promotional and paid credits.
X-Request-Id Identifier for this call. It appears in your usage log and in every error body — quote it in support requests.