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

  1. 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.
  2. Check it with the business. The suggestions can be wrong. The business, or the person acting for it, corrects anything that is.
  3. Apply (POST /applications). You get 201 and an id. The application has been received. It has not been listed.
  4. 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 consent to true only 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 in agency_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

FieldNeededWhat it is
countryNoGB. Assumed if left out.
nameYesThe contact person at the business, or who applies for it. Up to 120 characters.
businessYesThe business's name.
emailYesAn address the business reads. We email it a confirmation link. It can be any address the business uses, not only one on its website.
phoneYesAn 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_phoneNoA 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_showNotrue to show the number on the listing. A number the website shows is always shown. Default false.
tradeYesWhat the business does, for example Plumbers. Use the look-up's suggestion where it fits.
townYes, unless online_onlyThe town or city.
online_onlyNotrue if the business sells only online and has no premises customers visit. It must still be in the country, and have its own website.
websiteYesThe business's own website.
messageNoWhat the business does, in a few sentences. Up to 2,000 characters.
consentYesMust be true. See Before you apply.
submitterYesowner, staff or agency (an agency, assistant or AI agent applying for the business).
agency_name, agency_toldFor agencyWho you are, and true to confirm the business knows about the application and knows we will email and ring it.
lookup_refWith a look-upFrom 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_failedNoWhy 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.
timezoneNoThe 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:

StatusMeaning
receivedWaiting for a person to read it. There is no fixed time.
checkingAdded 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.
liveListed. links.listing is its page.
removedThe business asked for its listing to be removed.
closedNo 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"
    ]
}
StatusCodeWhat to do
400invalid_json, idempotency_key_invalidFix the body, or the key.
413, 415payload_too_large, unsupported_media_typeThe body is up to 32 KB, and has to be JSON with Content-Type: application/json.
422validation_failedA field is missing, the wrong type or too long. errors lists them all.
422country_required, country_invalid, country_not_servedSend country, and send it to the site that serves it (the problem names it).
422phone_format, phone_cost, phone_not_uk, phone_abroad, check_phoneThe number is not one we can use. phone_problem says why.
422phone_siteThe website shows other numbers. Use one of allowed_phones, or give the business's own in check_phone.
422website_needed, website_own, website_big, website_bare, website_ours, online_site, website_invalidThe business's own website is needed, and this address is not one.
422lookup_neededLook the website up first and send lookup_ref, or send lookup_failed if it could not help.
422website_unreadableWe could not read the website. Apply without the look-up, with lookup_failed: "unreadable".
422Confirm what the problem asks.
422not_listedThis is not a kind of business we list.
422idempotency_key_reusedThat key was used for a different request. Use a new key for a different application.
403not_acceptedWe cannot accept this application. The answer is the same whatever the reason, as on the website form. Do not retry with the same details.
409listedThe business is already listed on that page. listing_url is its listing and update_url is where to ask for a change.
404not_foundNo such application, or it has been deleted.
429rate_limitedSlow down. Wait for Retry-After seconds.
503signups_closed, busy, api_closed, api_not_ready, lookup_unavailable, send_failedNot 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.
500server_errorOur 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-Remaining and RateLimit-Reset come with the answer, and Retry-After with a 429 or 503. 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) with POST /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, marked Idempotency-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 real agency_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_listed or listed answer 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.