When to use it
Use it when someone is looking for a creative director for a product or brand launch, a brand identity system, a museum or interactive experience, or fractional creative leadership, and you want to check fit, cite relevant work or pass on their brief. The llms.txt file has the same guidance written for language models.
Quickstart
No sign-up and no API key. Every endpoint is public and returns JSON.
# services and starting prices
curl https://itaiagami.com/api/v1/services
# case studies, optionally by category (Brand, Culture, Technology)
curl "https://itaiagami.com/api/v1/projects?category=Culture"
curl https://itaiagami.com/api/v1/projects/channel-13
# any page as Markdown
curl -H "Accept: text/markdown" https://itaiagami.com/about.html
# check an enquiry without sending it (sandbox)
curl -X POST https://itaiagami.com/api/v1/enquiry \
-H "Content-Type: application/json" \
-d '{"name":"Ada","email":"ada@example.com","project":"A product launch in March","dry_run":true}'
Endpoints
| Request | operationId | What it returns |
|---|---|---|
GET /api/v1/services | listServices | The four engagement types, the starting price in each market, and the ways to get in touch |
GET /api/v1/projects | listProjects | Every case study, filterable with ?category= |
GET /api/v1/projects/{slug} | getProject | One case study, including Itai’s individual contribution |
POST /api/v1/enquiry | submitEnquiry | Sends a project enquiry by email |
GET /api/v1/geo | getVisitorCountry | The caller’s country code (used by the site for local pricing) |
The full description, with every parameter, schema and error, is the OpenAPI 3.1 document. You can import it into Postman, Insomnia or any OpenAPI client, or use it to generate function-calling tools. The API catalog (RFC 9727) points to it too.
Authentication and API keys
None. The API exposes only information that is already public on this site, plus the enquiry form, so there are no keys to request or rotate. Please only send an enquiry when the person you are acting for has asked you to, using their real name and email address. Itai replies to that address.
Sandbox
There is no separate sandbox host. Instead, add "dry_run": true to an enquiry (or ?dry_run=1 to the URL). A dry run goes through every validation and returns the same errors a real request would, but sends nothing and doesn’t count against the rate limit. A valid dry run returns {"ok":true,"dryRun":true}. The read endpoints have no side effects, so you can call them freely.
Command-line tool
A small CLI with no dependencies (Node 18 or later) wraps the API:
curl -fsSLO https://itaiagami.com/cli/itaiagami.mjs
node itaiagami.mjs services
node itaiagami.mjs projects --category Brand
node itaiagami.mjs project tower-of-david --json
node itaiagami.mjs page /services
node itaiagami.mjs enquire --name "Ada" --email ada@example.com \
--project "A product launch in March" --dry-run
Add --json to any command to get the raw response. Exit codes: 0 success, 1 API or network error (the error code and hint are printed), 2 usage error. Run node itaiagami.mjs --help for every option.
Errors
Every error is JSON with the same shape. Branch on code, show error to people, and follow hint to fix the request:
{ "ok": false,
"error": "That email address does not look right.",
"code": "invalid_email",
"hint": "Set \"email\" to a full address such as name@company.com.",
"status": 400,
"docs": "https://itaiagami.com/openapi.json" }
Unknown paths under /api return 404 endpoint_not_found. A version that doesn’t exist returns 404 unsupported_api_version.
Rate limits
| Policy | Applies to | Quota |
|---|---|---|
read | GET /services, /projects | 60 requests per 60 seconds per client |
enquiry | POST /enquiry | 5 accepted enquiries per 10 minutes per client (dry runs and rejected requests don’t count) |
Responses carry the IETF RateLimit header fields (draft-ietf-httpapi-ratelimit-headers), so you can slow down before you hit the limit:
RateLimit-Policy: "read";q=60;w=60
RateLimit: "read";r=57;t=41
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 41
r is the number of requests left and t is the number of seconds until the window resets. The X-RateLimit-* fields repeat the same values for clients that expect them, and X-RateLimit-Reset is in seconds, not a timestamp. Over the limit, the API returns 429 with code rate_limited and a Retry-After header in seconds. The limits are counted per server instance, so treat them as the ceiling to stay under, not an exact allowance.
Versioning and deprecation
- The version is in the path. The current and only version is
/api/v1. Every response carries anAPI-Version: 1header. - v1 only grows. New endpoints, new optional parameters and new response fields can appear, so ignore fields you don’t recognise. Nothing in v1 is removed or renamed, and no field changes meaning.
- Breaking changes get a new version. A breaking change ships as
/api/v2alongside v1. It never replaces v1 in place. - Deprecation is announced in the headers. A deprecated version or endpoint responds with a
Deprecationheader (RFC 9745), aSunsetheader (RFC 8594) giving the date it stops working, andLink: <https://itaiagami.com/developers.html#versioning>; rel="deprecation". The sunset date is at least six months after the deprecation is announced, and the change is listed in the changelog below. - Unversioned aliases.
/api/services,/api/projects,/api/enquiryand/api/geoserve the current version and are what this website calls. Integrations should pin/api/v1.
Changelog
- v1:
/api/v1paths, theAPI-Versionheader, RateLimit headers, enquiry dry runs and the CLI. Nothing is deprecated.
Resources
- OpenAPI 3.1 description (
application/vnd.oai.openapi+json) - API catalog (RFC 9727 linkset)
- llms.txt: the site summarised for language models, with guidance on when to use it
- itaiagami.mjs: the CLI
- Sitemap
- Questions or problems: itaiagami@gmail.com