tattoo
On Map
← Back to directory

thetattoo.world API documentation

Public read API for the tattoo artist directory. No API key.

Authentication

The public API is read-only. It does not use an API key, bearer token, OAuth scope, or session cookie. Call the endpoints over HTTPS with no Authorization header. Google sign-in on the website only saves favourites and submits suggestions or corrections for a person using the browser. Those actions are not operations in this API. Sending a Supabase session cookie does not change an API response, and you should not send one.

There is no write API, no webhook, and no API credential to provision. To add or correct an artist, a person uses the website or opens a GitHub issue. Agents should treat the catalogue as published data and should not attempt to authenticate.

Rate limits

Each server instance keeps its own sliding window of 60 seconds, keyed by client IP and route group. The same client can be counted separately on another instance. GET /api/artists/compact allows 90 requests. GET /api/artists/{id} allows 180 requests. GET /api/map-data allows 120 requests. POST /api/map-hex-artists allows 60 requests. When a limit is exceeded the response is HTTP 429 with a JSON body { "error": "Too many requests" }, a Retry-After header of 60, and X-RateLimit-Limit set to that group's maximum. Cache the compact list instead of polling it. The API is not a bulk-export firehose.

Endpoints

Every operation has a unique operationId, a description, typed parameters, and a response schema in the OpenAPI specification at /openapi.json. The four operations below are the whole public surface. Paths are on https://thetattoo.world.

List artists

GET /api/artists/compact returns a JSON array of the artists currently shown in the directory. operationId: listArtists. There are no query parameters. Each object includes id, name, location (city and country), styles, links.instagram, and tattoo_count, plus optional biography, thumbnail, and follower fields. The response is cacheable for an hour. This is the call to make when you need to search or filter locally.

Get an artist

GET /api/artists/{id} returns one artist. operationId: getArtistById. The id is the lowercased Instagram handle, 1 to 30 characters from a-z, digits, dot, and underscore. A known public artist returns HTTP 200 and a JSON object with location, styles, links, biography, and a tattoos array of image URLs. An unknown id, a hidden record, or an id that fails the pattern returns HTTP 404 and a JSON null body.

Map points

GET /api/map-data returns aggregated points for the map. operationId: getMapPoints. The optional query parameter style is a string. When style is set, each point is a city and country with a count of artists who list that style. When style is omitted, each point is a city, country, and style so a map can colour hexes by the dominant style. The JSON object has points, styles, and totalArtists. Points without coordinates are omitted.

Artists at map locations

POST /api/map-hex-artists lists artists whose city and country match one of the posted locations. operationId: listArtistsAtLocations. The JSON body is { "locations": [{ "city": "Porto", "country": "Portugal" }], "style": "traditional" }. style may be omitted or null. The response is { "artists": [{ "id": "example", "name": "Example" }] }, sorted by name. An empty locations array returns an empty artists array. A body that is not JSON returns HTTP 400 and { "error": "Invalid JSON" }.

Example requests

These commands call the live origin. Replace the artist id with a real handle from the compact list.

curl -sS https://thetattoo.world/api/artists/compact
curl -sS https://thetattoo.world/api/artists/example
curl -sS 'https://thetattoo.world/api/map-data?style=traditional'
curl -sS -X POST https://thetattoo.world/api/map-hex-artists \
  -H 'Content-Type: application/json' \
  -d '{"locations":[{"city":"Porto","country":"Portugal"}]}'

Machine-readable description

The OpenAPI specification is published at https://thetattoo.world/openapi.json. It is the source agents should load for function calling: unique operationId values, parameter schemas, and response schemas. llms.txt at https://thetattoo.world/llms.txt says when to call this API. The sitemap at https://thetattoo.world/sitemap.xml lists indexable pages. Request any of those documents, or this page, with Accept: text/markdown to receive Markdown.