Application API
Apply for a listing from your code or your agent
The same application as the List your business form, as JSON over HTTPS. No key or sign-in. A person reads every application, and nothing is listed until the business has passed the checks for its country.
Nobody can pay to be listed, to be verified or to rank higher, and that includes through the API. The API makes applying easier. It does not change who gets listed.
How it works
- Look up the website (
POST /lookups, optional but expected). We read the business's own website and suggest its name, phone number, email address, trade and town. - Check it with the business. The suggestions can be wrong. The business, or the person acting for it, corrects anything that is.
- Apply (
POST /applications). You get201and anid. The application has been received. It has not been listed. - Follow it (
GET /applications/{id}). A person reads it. We then email the business, which has to approve its listing. Where there is a phone check, we also ring or text the business. When every check has passed, the listing goes live by itself.
Base address: https://www.bestratedcompany.co.uk/api/v1/. The machine-readable description is /api/v1/openapi.json (OpenAPI 3.1), and the API is listed at /.well-known/api-catalog.
Before you apply
- Countries. This site takes applications for United Kingdom (GB). United States is on bestrated.company. Canada is on bestrated.company.
- The business needs its own website, showing its phone number and email address. A social page, a marketplace shop or a listing on another directory is not enough, and neither is a business that only has one of those.
- Consent. The business has to be happy for us to email the address you give and, where there is a phone check, to ring or text the phone number. Set
consenttotrueonly if that is so. If you are an agency, an assistant or an AI agent applying for the business, say so (submitter: "agency",agency_told: true) and tell us who you are inagency_name. - What we do not list. The terms list the kinds of business we turn away. Please do not send those.
- The business must be the one asking. Do not apply for a business that does not know about it. The confirmation email goes to the business, not to you, and it does nothing unless the business approves it.
Quick start
1. Look up the website
curl -sS https://www.bestratedcompany.co.uk/api/v1/lookups \
-H 'Content-Type: application/json' \
-d '{ "url": "www.taylorplumbing.example" }'
It can take up to a minute, so allow 90 seconds. The answer holds the suggestions in found, every phone number and email address the website shows in site_contacts, and a lookup_ref that is good for 24 hours.
2. Apply
curl -sS https://www.bestratedcompany.co.uk/api/v1/applications \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 6b7e1c2e-3d4f-4a5b-8c9d-0e1f2a3b4c5d' \
-d '{
"name": "Sam Taylor",
"business": "Taylor & Sons Plumbing",
"email": "hello@taylorplumbing.example",
"phone": "01632 960123",
"trade": "Plumbers",
"town": "Leeds",
"website": "https://www.taylorplumbing.example",
"message": "Boiler servicing and repairs, bathrooms and emergency call-outs.",
"consent": true,
"submitter": "agency",
"agency_name": "ExampleAssistant, run by Example Ltd",
"agency_told": true,
"lookup_ref": "a1b2c3d4e5f60718293a4b5c"
}'
The answer, 201 Created with a Location header:
{
"id": "4f9c2e7a1b3d4c8e9a0b5d6f7e8a9b0c",
"status": "received",
"summary": "Application received. It has not been listed: it goes through the steps below first.",
"country": "GB",
"checks": [
"lookup",
"phone",
"email"
],
"what_happens_next": [
"A person reads the application. Nothing is listed until they have, and there is no fixed time for that.",
"..."
],
"links": {
"self": "https://www.bestratedcompany.co.uk/api/v1/applications/4f9c2e7a1b3d4c8e9a0b5d6f7e8a9b0c"
}
}
3. Follow it
curl -sS https://www.bestratedcompany.co.uk/api/v1/applications/4f9c2e7a1b3d4c8e9a0b5d6f7e8a9b0c
The answer has no personal details in it: no name, email address or phone number. The id is the secret, so keep it to yourself and the business. Poll gently: once every few minutes is plenty, and the answer changes mostly when a person or the business acts.
The application
| Field | Needed | What it is |
|---|---|---|
country | No | GB. Assumed if left out. |
name | Yes | The contact person at the business, or who applies for it. Up to 120 characters. |
business | Yes | The business's name. |
email | Yes | An address the business reads. We email it a confirmation link. It can be any address the business uses, not only one on its website. |
phone | Yes | An ordinary business number for the country: not premium rate, and not abroad. When the look-up read the website, it has to be one the website shows (site_contacts.phones). |
check_phone | No | A different number the business answers, for our call or text only. It is never shown. Use it when the number on the website is not one the business answers. |
phone_show | No | true to show the number on the listing. A number the website shows is always shown. Default false. |
trade | Yes | What the business does, for example Plumbers. Use the look-up's suggestion where it fits. |
town | Yes, unless online_only | The town or city. |
online_only | No | true if the business sells only online and has no premises customers visit. It must still be in the country, and have its own website. |
website | Yes | The business's own website. |
message | No | What the business does, in a few sentences. Up to 2,000 characters. |
consent | Yes | Must be true. See Before you apply. |
submitter | Yes | owner, staff or agency (an agency, assistant or AI agent applying for the business). |
agency_name, agency_told | For agency | Who you are, and true to confirm the business knows about the application and knows we will email and ring it. |
lookup_ref | With a look-up | From POST /lookups. Without one, the website form's rule applies: if a look-up could have helped, the application is turned back (lookup_needed). |
lookup_failed | No | Why there is no lookup_ref: unreadable, error, busy, limit, off or listed. We check it against our own record, so it only works when it is true. |
timezone | No | The business's IANA time zone, for example Europe/London. |
There is no news-emails option: the API never signs anyone up to marketing.
Correcting what the look-up found
Yes, the phone number and email address can be changed before applying, by the business or by you for it. The email can be any address the business reads. The phone has to be a number the website shows, or the business gives a different number for our checks in check_phone. If the website shows no phone number, any valid number is accepted and the email to us says it was typed in.
What happens after you apply
GET /applications/{id} returns one status:
| Status | Meaning |
|---|---|
received | Waiting for a person to read it. There is no fixed time. |
checking | Added to the directory. The checks are under way. checks shows each one as not_started, waiting_for_business, in_progress, passed or needs_attention, and next_step says what has to happen and who has to do it. |
live | Listed. links.listing is its page. |
removed | The business asked for its listing to be removed. |
closed | No longer open. |
An application that a person declines is deleted, and then returns 404, as one does 90 days after it arrived. We do not say why a particular application was declined.
Errors
Errors are RFC 9457 problem details, as application/problem+json. Read code: it does not change. detail is written for a person and may. errors lists each field that has to change, with its own code. Some problems add a member that helps, for example allowed_phones, listing_url or lookup_failed.
{
"type": "https://www.bestratedcompany.co.uk/developers/#problem-phone_site",
"title": "The application has a problem",
"status": 422,
"code": "phone_site",
"detail": "Please use a phone number shown on the business's website: it is the number its customers use, so it is the one on the listing.",
"errors": [
{
"field": "phone",
"code": "phone_site",
"detail": "..."
}
],
"allowed_phones": [
"01632 960123"
]
}
| Status | Code | What to do |
|---|---|---|
| 400 | invalid_json, idempotency_key_invalid | Fix the body, or the key. |
| 413, 415 | payload_too_large, unsupported_media_type | The body is up to 32 KB, and has to be JSON with Content-Type: application/json. |
| 422 | validation_failed | A field is missing, the wrong type or too long. errors lists them all. |
| 422 | country_required, country_invalid, country_not_served | Send country, and send it to the site that serves it (the problem names it). |
| 422 | phone_format, phone_cost, phone_not_uk, phone_abroad, check_phone | The number is not one we can use. phone_problem says why. |
| 422 | phone_site | The website shows other numbers. Use one of allowed_phones, or give the business's own in check_phone. |
| 422 | website_needed, website_own, website_big, website_bare, website_ours, online_site, website_invalid | The business's own website is needed, and this address is not one. |
| 422 | lookup_needed | Look the website up first and send lookup_ref, or send lookup_failed if it could not help. |
| 422 | website_unreadable | We could not read the website. Apply without the look-up, with lookup_failed: "unreadable". |
| 422 | consent, agency_told, submitter, email | Confirm what the problem asks. |
| 422 | not_listed | This is not a kind of business we list. |
| 422 | idempotency_key_reused | That key was used for a different request. Use a new key for a different application. |
| 403 | not_accepted | We cannot accept this application. The answer is the same whatever the reason, as on the website form. Do not retry with the same details. |
| 409 | listed | The business is already listed on that page. listing_url is its listing and update_url is where to ask for a change. |
| 404 | not_found | No such application, or it has been deleted. |
| 429 | rate_limited | Slow down. Wait for Retry-After seconds. |
| 503 | signups_closed, busy, api_closed, api_not_ready, , send_failed | Not now. Wait for Retry-After seconds. When the look-up is the problem, the answer names what to send as lookup_failed, so you can still apply. |
| 500 | server_error | Our fault. Try again in a few minutes. |
Limits, repeats and timeouts
- Applications: 10 an hour and 30 a day from one connection.
RateLimit-Limit,RateLimit-RemainingandRateLimit-Resetcome with the answer, andRetry-Afterwith a429or503. Applications that were only wrong in some field do not count. - Look-ups: 6 an hour and 15 a day from one connection. The same website looked up again within a day is answered from the stored result and costs nothing.
- Everything else: a generous limit on how fast one connection may send requests. A program that polls once every few minutes will never meet it.
- Idempotency. Send an
Idempotency-Key(16 to 128 characters, a UUID is fine) withPOST /applications. If your request times out or the connection drops, send it again with the same key and the same body: you get the first answer back, markedIdempotency-Replayed: true, and no second application is made. Keys are kept for 24 hours. - Timeouts. A look-up can take up to a minute. Set your client's timeout to 90 seconds for
POST /lookups. An application is usually answered within a few seconds; allow 30 seconds. - Connections. Many agents share an address with other people, so the limits are generous and an address is never used to block anyone from the API.
If you are an AI agent
- Find this API from
https://www.bestratedcompany.co.uk/.well-known/api-catalog, read/api/v1/openapi.json, and see llms.txt for what the directory is. - Apply only when the person you act for has asked you to list their business, and has seen the details. Do not apply for businesses you were not asked about, and never to see what happens.
- Say who you are:
submitter: "agency"and a realagency_name. A person reading the application sees it, and it helps. - Do not invent a phone number, an email address or a website. If something is missing, ask the person.
- Do not retry a
not_accepted,not_listedorlistedanswer with changed details to get past it. Each refused application is read by a person, and repeated attempts get the person blocked. - Tell the person what happens next: a person reads the application, then the business has to approve the email we send it, and where there is a phone check, answer our call or text. The listing goes live by itself only when every check has passed.
Changes
This is version 1. We may add fields, answers and codes at any time, so ignore anything you do not recognise. If we ever need to change what something means, it will be /api/v2/, and version 1 will keep working for a good while after.
Questions or problems: use the chat on the contact page.