Building an integration with AI coding tools
If you are implementing your integration with an agentic coding tool — Claude Code, OpenAI
Codex, Cursor, GitHub Copilot, or your own agent — this site is published in machine-readable
form so the tool can work from the API contract directly instead of scraping these rendered
pages. Everything below is served from https://api-reference.alamy.com, the canonical home for
this documentation.
Machine-readable entry points
/llms.txt— a compact index of the whole site: the OpenAPI document, every operation, and a link to each guide. Give the agent this first; it is the cheapest way for it to discover everything else./openapi.json(or/openapi.yaml) — the complete OpenAPI contract: every endpoint, its request and response schemas, and the OAuth 2.0 security scheme. This is the source of truth for generating a client or reasoning about payloads. The API Reference page renders this same document with JavaScript — an agent that cannot execute JavaScript sees only aLoading API reference…placeholder, and each endpoint lives at an in-page#/operations/…fragment rather than its own URL — so for endpoint detail an agent should read the spec file, not the reference HTML./llms-full.txt— the prose of these guides concatenated into a single file, for when the agent needs endpoint behaviour, limits and metadata meaning alongside the schema.
/openapi.json always describes the API as it is deployed now; its info.version tells you which
revision you are looking at. See the Changelog for what has changed.
Generate a client rather than hand-writing calls
Because /openapi.json is a complete contract, the agent need not hand-write HTTP calls throughout
your codebase. Point an SDK generator — or an OpenAPI-to-MCP tool — at it to produce a typed client
or an MCP server, then build the integration against that. It gives you one place for
authentication, retries and rate limiting, and a clean surface to expose as tools to an agent
framework. The operations it will find are search, item, items, downloadItemById,
downloadItemByIdLicensed, feed and orders.
Keep the agent grounded in the fetched spec rather than its own recollection of the API: the
schemas, enums and error shapes all come from /openapi.json, which is generated from the same
source the service is built against and so cannot drift from it. A prompt along these lines works
well:
Read https://api-reference.alamy.com/llms.txt and fetch the OpenAPI document it
links. Working only from that spec, implement <the endpoints my plan needs>
against my design. Authenticate with OAuth 2.0 as the spec describes, and add
client-side rate limiting. Do not call the download endpoints - they are
recorded against my account.
For a worked example of the whole sequence — token, search, metadata, download — see A complete first integration.
Endpoints with side effects
Only the download operations have any effect beyond returning data. Everything else is a read: it costs nothing and can be called freely from development and test runs.
| Operation | Method and path | Effect |
|---|---|---|
search | GET /search | Read-only, free |
item | GET /item/{id} | Read-only, free |
items | GET /item?ids=… | Read-only, free |
feed | GET /feed | Read-only, free; holds the connection for up to five seconds |
orders | GET /orders | Read-only, free; long-polls when dateFrom is supplied |
downloadItemById | GET /download/{id} | Logged as a download against your account |
downloadItemByIdLicensed | POST /download/{id} | Decrements your licence pack |
There is no dry-run or preview mode on either download operation. The GET is recorded whether or
not you follow the signed URL it returns; it is not an immediate charge — usage is declared later if
you go on to use the item — while the licensed POST is the spend action. Two consequences worth
handing to an agent:
- Gate the download step behind a deliberate decision to download, not behind a code path a test, a retry or a batch job can reach.
- Never blind-retry a failed download: a duplicate download record may be counted as usage later,
and
GET /orderswill not settle whether the first call was recorded, because it lists confirmed purchases rather than download records (see Errors).
A safe read-only integration
Scopes are the enforcement point, not convention. A token minted with only
https://api.alamy.com/v3/scopes/search and https://api.alamy.com/v3/scopes/item cannot download
or spend anything even if it leaks — /download returns 401 — so it is the right credential for
the part of your system that browses content, and for anything an agent runs unattended.
Add the download scope in the one code path that downloads, and mint that token separately. See
Scopes for the full list and the exact request.
Testing without spending production budget
Ask your account manager for a pre-production account alongside your production one. It is usually set up at onboarding if you request it, and can be added later.
The two accounts differ only in their credentials: the same https://api.alamy.com/v3 base URL,
the same behaviour, so one environment variable switches between them. What the pre-production
account gives you is a download test quota agreed with your account manager, letting you prove
the download path end to end without recording test downloads against production — which keeps your
production account's download and order history clean for auditing.
Because the quota is finite:
- Exercise search, item, feed and orders as much as you like against either account — they are free.
- Spend the pre-production quota on the handful of real downloads that prove your download path, not on a test suite that runs on every commit.
- Tell your agent explicitly that the quota is limited, and that download must never be called in a loop or a retry storm.
Reading the documentation itself
The documentation is public and robots.txt permits agent crawlers, so no credentials are needed
to read it — only to call the API. Every page also advertises the OpenAPI document through an
RFC 8631 service-desc link in its <head>, but not
every tool looks there — so if a tool does not appear to have found the contract, hand it the
explicit URLs above rather than expecting it to discover them from the site root.
Two constraints shape a correct integration and are easy to get wrong from the schema alone, so state them to the agent directly:
- Rate limits — the API allows 15 requests per second per source IP across all endpoints and returns no rate-limit headers, so have the agent apply its own client-side limiting and backoff rather than probing for the ceiling (see Request Limits).
- Error handling — every status code, its cause and whether it is worth retrying are catalogued in Errors, along with a worked retry loop; point the agent there so it can recover from failures rather than guessing from the status alone.