Skip to the content

DoRoutes API · version 1

Website

GET/v1/site/shell

A firm's website page

For the web server in front of the firms' websites: answers a page request with the site's built index.html, its head filled in for the firm found by the address. The firm is the one whose verified domain is `host`, or else the one whose slug is `slug`. The head holds the title, description, Open Graph tags, schema.org `MovingCompany` data and a `<script id="firm" type="application/json">` block with the firm's `key`, `slug`, `base` (the path its pages sit under: empty on its own domain, else `/` and its slug), `name`, `live`, public `config`, `photos` (each slot's photo paths by width) and `job_types` (the types offered online, as `GET /v1/config` gives them). An unknown address or a suspended firm is answered with a plain not found page.

Parameters

  • hoststring, in the query

    The host the visitor asked for; its case, port and trailing dot are ignored.

  • slugstring, in the query

    The firm's slug, from an address such as `app.<domain>/<slug>`.

  • pathstring, in the query

    The page's path, for its canonical address.

Response 200

The page.

Response 404

No firm at this address.

Response 500 · Error

Something failed on our side.

  • errorobject, required
    • codestring, required

      A short machine-readable name, such as not_found.

    • messagestring, required

      What went wrong, for people.

  • request_idstring, required

    Matches the X-Request-ID response header.

Example response 500
{
  "error": {
    "code": "string",
    "message": "string"
  },
  "request_id": "string"
}

Response 503

This server has no built site (`SITE_INDEX` is not set).

GET/v1/site/firm

A firm's website data

The `<script id="firm">` block `GET /v1/site/shell` puts in a page's head, as JSON, for the firm found by the address in the same way; it needs no built site. The website's local development server starts from it. An unknown address or a suspended firm is not found.

Parameters

  • hoststring, in the query

    The host the visitor asked for; its case, port and trailing dot are ignored.

  • slugstring, in the query

    The firm's slug.

  • pathstring, in the query

    The page's path.

Response 200 · object

The firm.

  • firmobject, required
Example response 200
{
  "firm": {}
}

Response 404 · Error

Not found, or not yours.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page

GET/v1/site/photos/{id}/{file}

A website photo

One width of a photo on a business's website, as the `urls` of a photo give it. A photo never changes, so it may be kept for a year.

Parameters

  • idstring, in the path, required
  • filestring, in the path, required

Response 200

The photo.

Response 404 · Error

Not found, or not yours.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page

GET/v1/site/tls-ask

Whether a domain is a firm's

For the web server's on-demand certificates. Answers 200 when the domain is an active firm's verified domain, and 404 otherwise.

Parameters

  • domainstring, in the query, required

Response 200 · object

The domain is a firm's.

  • servesboolean, required

    One of: true

Example response 200
{
  "serves": true
}

Response 404 · Error

Not found, or not yours.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page

GET/v1/admin/site/domain

The firm's own domain

Needs the settings.write permission. An empty `domain` when none is set.

Response 200 · SiteDomain

Done.

  • domainstring, required
  • txt_namestring, required

    The DNS name of the TXT record that proves the domain is the firm's, e.g. `_doroutes.www.example.co.uk`.

  • txt_valuestring, required

    The value the TXT record must hold.

  • verifiedboolean, required
  • site_urlstring, required

    The address the website is served at now, e.g. `https://www.example.co.uk` once the domain is verified, else under the DoRoutes address with the firm's slug.

Example response 200
{
  "domain": "string",
  "txt_name": "string",
  "txt_value": "string",
  "verified": true,
  "site_url": "string"
}

Response 401 · Error

No tenant key, or no valid session.

Fields as in A firm's website page

Response 403 · Error

The session may not do this.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page

PUT/v1/admin/site/domain

Set the firm's own domain

Needs the settings.write permission. A new domain starts unverified, with a new TXT record value; the same domain again changes nothing.

Request body · object

  • domainstring, required

    A host such as `www.example.co.uk`; its case, port and trailing dot are ignored. Empty removes the domain.

Example request
{
  "domain": "string"
}

Response 200 · SiteDomain

Done.

Fields as in The firm's own domain

Response 400 · Error

The request is not valid.

Fields as in A firm's website page

Response 401 · Error

No tenant key, or no valid session.

Fields as in A firm's website page

Response 403 · Error

The session may not do this.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page

POST/v1/admin/site/domain/verify

Check the firm's domain in DNS

Needs the settings.write permission. Marks the domain verified when its TXT record `txt_name` holds `txt_value`; the website is then served at it. 409 when another firm has verified the same domain.

Response 200 · SiteDomain

Done.

Fields as in The firm's own domain

Response 401 · Error

No tenant key, or no valid session.

Fields as in A firm's website page

Response 403 · Error

The session may not do this.

Fields as in A firm's website page

Response 404 · Error

Not found, or not yours.

Fields as in A firm's website page

Response 409 · Error

It clashes with what is stored.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page

GET/v1/admin/site/photos

The website's photos

Needs the settings.write permission. One photo a slot, by slot.

Response 200 · object

Done.

  • photosarray of SitePhoto, required
    • idstring, required
    • slotstring, required
    • urlsobject, required

      The API path of the photo at each width, by width (`1600`, `960`, `480`).

Example response 200
{
  "photos": [
    {
      "id": "string",
      "slot": "string",
      "urls": {}
    }
  ]
}

Response 401 · Error

No tenant key, or no valid session.

Fields as in A firm's website page

Response 403 · Error

The session may not do this.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page

POST/v1/admin/site/photos

Add a photo to the website

Needs the settings.write permission. A JPEG, PNG or WebP file of at most 10 MB and 40 megapixels, checked by its content. It is turned upright by its EXIF orientation, its metadata is dropped, and it is stored as WebP at 1600, 960 and 480 px wide (never wider than it is). It replaces any photo already in the slot. A transparent background is kept.

Response 200 · object

Done.

  • photoSitePhoto, required
    • idstring, required
    • slotstring, required
    • urlsobject, required

      The API path of the photo at each width, by width (`1600`, `960`, `480`).

Example response 200
{
  "photo": {
    "id": "string",
    "slot": "string",
    "urls": {}
  }
}

Response 400 · Error

The request is not valid.

Fields as in A firm's website page

Response 401 · Error

No tenant key, or no valid session.

Fields as in A firm's website page

Response 403 · Error

The session may not do this.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page

DELETE/v1/admin/site/photos/{id}

Remove a photo from the website

Needs the settings.write permission. Its files are deleted within the hour.

Parameters

  • idstring, in the path, required

Response 200 · object

Done.

  • removedboolean, required
Example response 200
{
  "removed": true
}

Response 401 · Error

No tenant key, or no valid session.

Fields as in A firm's website page

Response 403 · Error

The session may not do this.

Fields as in A firm's website page

Response 404 · Error

Not found, or not yours.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page

GET/v1/admin/site/live

Whether the website is live

Needs the settings.write permission.

Response 200 · SiteLive

Done.

  • liveboolean, required
  • confirmed_bystring

    The name of the staff member who confirmed the notices.

  • confirmed_atstring

    UTC, as 2026-10-05 12:00:00.

Example response 200
{
  "live": true,
  "confirmed_by": "string",
  "confirmed_at": "string"
}

Response 401 · Error

No tenant key, or no valid session.

Fields as in A firm's website page

Response 403 · Error

The session may not do this.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page

POST/v1/admin/site/live

Confirm the notices and put the website live

Needs the settings.write permission. Records who confirmed the privacy and cookie notices and when; the website is then live. 400 while either notice is empty. Confirming again records the new confirmation; editing the notices later keeps the website live.

Response 200 · SiteLive

Done.

Fields as in Whether the website is live

Response 400 · Error

The request is not valid.

Fields as in A firm's website page

Response 401 · Error

No tenant key, or no valid session.

Fields as in A firm's website page

Response 403 · Error

The session may not do this.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page

GET/v1/admin/site/notices/draft

Draft privacy and cookie notices

Needs the settings.write permission. The notices written from DoRoutes' template with the business's name, address, email and phone as they are now, and Google reCAPTCHA when it is on. Nothing is saved: the business edits them and saves them as `site_privacy_notice` and `site_cookie_notice`.

Response 200 · object

Done.

  • privacy_noticestring, required
  • cookie_noticestring, required
Example response 200
{
  "privacy_notice": "string",
  "cookie_notice": "string"
}

Response 401 · Error

No tenant key, or no valid session.

Fields as in A firm's website page

Response 403 · Error

The session may not do this.

Fields as in A firm's website page

Response 500 · Error

Something failed on our side.

Fields as in A firm's website page