Skip to content
kosto kosto API v1
OpenAPI Back to the dashboard

Kosto API · v1

Kosto API documentation:
domain authority, inside your own tools.

Query the authority score you see in the dashboard, the referring domains, side-by-side comparison and spam checks over HTTP. Every response is JSON, field names are written in snake_case, and every endpoint below comes with a working example.

Base URL
Endpoint
7
Per-minute limit
120
Format
JSON
Auth
API key

Authority score

A score from 0 to 100, ranks and the components that make up the score. One domain, or ten side by side.

Referrers

Domains that link to a domain, sorted by score; you set the lowest score.

Spam audit

Risk score and reasons for abuse traces such as gambling, adult, pharma, replica.

  • All endpoints live under /api/v1. The version is part of the address.
  • Requests and responses are UTF-8 JSON. Dates are written in ISO 8601 (UTC).
  • Machine-readable definition: download the OpenAPI 3.1 document.

Getting started

Quick start

Three steps from getting a key to the first response.

  1. 1

    Get a key

    Create a key below. The key is visible only at the moment it is created; copy it and save it somewhere safe.

  2. 2

    Send the first request

    Send the key in the Authorization header. The example on the right is ready in the language you choose; replace YOUR_API_KEY with your own key.

  3. 3

    Read the response

    The authority_score field is the score from 0 to 100. If found is false, the domain is not in the link index; this is not an error and 200 is returned. score_source tells you what kind of score it is: data is data-based, while standard and calibrated are approximate scores.

Under every endpoint, the Try panel lets you send the request straight from your browser. The key is held only in the memory of this tab, is not saved anywhere, and no request is sent until you press the button.

Getting started

Authentication

Every endpoint except /api/v1/openapi.json requires an API key. A key starts with op_ and is 35 characters long. Use one of the two headers below; both do the same job.

HTTP headerFormat
AuthorizationBearer op_… (Bearer is case-insensitive)
X-API-Keyop_…

Protecting the key

  • The server stores not the key itself but its SHA-256 digest. If you lose it, generate a new key and revoke the old one.
  • Keep the key in an environment variable or in your secret vault. Do not put it in source code, public repositories or code that runs in the browser.
  • A revoked key gets 403 key_revoked. If the key is missing or malformed, 401 is returned.
  • No CORS header is sent, so browser code on another site cannot read this API (cross_site_forbidden). Scripts, the command line and server-side code work without any problem.
  • In account mode a key belongs to an account and is counted against that account's plan; a key whose account is suspended, or which is not linked to any account, gets 403.

Getting started

Rate limits and quotas

There are two separate limits: the per-minute rate limit is the same for all keys, while the monthly and daily quotas depend on your plan.

Rate limit: 120 requests per minute

Each key can make 120 requests in a fixed 60-second window. The window opens with the key's first request, closes 60 seconds later, and the counter is reset. Requests that do not send a valid key are counted in a shared window per client address. Rejected requests (such as 401 or 400) are also counted in the window. Every /api/v1 response carries these headers:

HTTP headerMeaning
X-RateLimit-LimitNumber of requests allowed per window (120).
X-RateLimit-RemainingNumber of requests left in the current window.
X-RateLimit-ResetThe moment the window closes, in Unix seconds.
Retry-AfterThe number of seconds to wait on 429 and 503 responses.

When the limit is exceeded, 429 rate_limited is returned. Wait for the time given in Retry-After and try again; retrying without waiting only fills the window further.

Plan quotas

In account mode every call deducts one from the API requests counter. A bulk query spends as many bulk query rows as it has rows, and a spam audit spends one spam audit. A failed call gives back what it spent. A spam audit of the same domain on the same day is not counted again (except with fresh=1).

PlanAPI keyAPI requests / monthBulk rows / daySpam audits / day

Daily and monthly quotas renew at midnight and at the start of the month in Türkiye time (UTC+3). When a quota is used up, 429 quota_exceeded is returned; the message says which counter is used up, your usage and your plan. See the plans page for prices.

Getting started

Error codes

Errors come with an HTTP status code and always have the same body. The code is stable, so your program should branch on it. The message is a description written for people and may change; it is in English by default, and you can choose another language with the Accept-Language or X-Kosto-Lang header.

StatusCodeWhen
  • On 5xx and 429 responses, wait for the time in the Retry-After header if it is present. Do not repeat a 4xx response with the same request; fix the request instead.
  • On a 405 response, the Allow header tells you which method the endpoint supports. HEAD is handled like GET.
  • While the link index is loading, reference queries may return 503 graph_unavailable; try again after Retry-After: 15.

Getting started

Pagination and bulk requests

The API uses neither cursors (cursor) nor page numbers. Endpoints that return lists answer with a single response, and its size is limited by parameters.

EndpointRule
GET /backlinkslimit is at most 1000 (default 100). The server first picks the best references by score, and the min_score filter is applied within the 1000 best references by link rank. That is why returned can be smaller than limit when you filter. total is the total number of references, independent of the filter.
GET /compareBetween 2 and 10 domains. Spellings that lead to the same site collapse into one row; after the reduction at least two different sites must remain.
POST /bulkAt most 1000 domains per request, and the body is at most 1 MB. If you exceed this you get too_many_domains (400) or payload_too_large (413). Empty lines are skipped, the same site collapses into one row, and invalid entries stay in place as valid: false; the order is the order of first appearance.

Splitting large lists

If you have more than 1000 domains, split the list into chunks of 1000 and send them one after another. Each chunk is one request and counts toward the per-minute limit; in account mode it also spends as much bulk query quota as it has rows.

Other

Versioning and changelog

The version is part of the address: /api/v1. The info.version field of the OpenAPI document gives the document version of this API version.

  • New endpoints and new fields in responses can be added without changing the version. We expect your client to ignore fields it does not know.
  • Incompatible changes, such as changing the type or meaning of an existing field or removing a field, arrive with a new version (/api/v2).
  • message texts may change. Rely on the code values and the HTTP status codes.
  1. 1.0.0Current version

    First release. Seven endpoints: domain, backlinks, compare, bulk, spam, usage and openapi.json.

    • Key authentication: Authorization: Bearer or X-API-Key.
    • A rate limit of 120 requests per minute and the X-RateLimit-* headers.
    • Error format: { "error": { "code", "message" } }.

Other

Frequently asked questions

Domain not found, is that an error?

No. For a domain that is not in the link index, 200 and found: false are returned. In that case subdomains and referring_domains are null. An invalid input (text that is not a domain) returns 400 invalid_domain instead.

Can I send a URL?

Yes. The domain parameter accepts a domain or a URL. https://www.example.com/page becomes example.com in the response. The same applies to bulk and compare.

Why is the referring domain count sometimes null?

referring_domains is null if the domain is not in the link graph or the graph cannot answer at that moment. backlinks returns 503 graph_unavailable while the graph is not ready.

Is the score approximate or data-based?

Look at the score_source field. If it is data, the score was calculated from measured link and traffic data; the dashboard shows it with a data-based badge and a filled dot. standard and calibrated are approximate scores; the dashboard gives them an approximate badge and an empty dot. When score_low and score_high are present they give the expected range of the score, and the dashboard draws that range as an arc on the dial. If both are null, no range is reported; it does not mean a range of zero width.

Why can the reference count in the panel differ from the one in the API?

referring_domains is always the number of referring domains counted in the link index, and the backlinks endpoint lists those domains by name. The dashboard shows a single number in the heading: the search data count if search data has been opened for the domain, otherwise the link index count. When the search data count is in the heading, the link index count appears in the detail below the card, as the number we are “able to list by name”. The two numbers are measured with different methods, and one does not contradict the other.

Why can the spam audit be so slow?

On the first query the archive, crawl and live page data of the domain are read, which can take up to 25 seconds. The result is cached for 24 hours (cached: true). Set your client timeout to at least 30 seconds. fresh=1 skips the cache and scans again.

Can I call it from the browser, from my own site?

No. The API sends no CORS header and rejects browser requests coming from other sites. Putting your key in browser code would not be safe anyway; make the call from your own server. The Try panel on this page is the exception, because it runs from the same address.

I lost my key.

A key cannot be recovered; only its digest is stored. Create a new key, update your script and revoke the old one.

How do I see my limit?

GET /api/v1/usage returns the total request count of your key and the state of the current per-minute window. In account mode, the X-Quota-* headers on successful responses show what is left of the quota counted last; the details are on your account page.

Which time zone are the timestamps in?

The date fields in responses are in UTC (like 2026-11-10T09:40:36.000Z). Daily and monthly quotas renew according to Türkiye time (UTC+3).