Developer documentation
Integrate with Tankyu Distillery
This page documents the machine-readable surface of tankyudistillery.jp for AI agents, coding assistants, and partners building directories or commerce integrations. Everything here is read-only and requires no authentication.
Quickstart
Prefer JSON endpoints over HTML scraping. The four most useful discovery entry points:
curl https://tankyudistillery.jp/api/facts.json curl https://tankyudistillery.jp/api/products.json curl https://tankyudistillery.jp/api/tour.json curl -H "Accept: text/markdown" https://tankyudistillery.jp/
All JSON endpoints are CORS-enabled (Access-Control-Allow-Origin: *) and cached for 24 hours at the edge.
Authentication
None. All public content and static JSON feeds are unauthenticated. The /.well-known/oauth-* and /.well-known/openid-configuration documents exist only for RFC 8414 / RFC 9728 compliance so agent-readiness probes can verify our access model. They declare empty response_types_supported and should not be treated as live OAuth endpoints.
POST form endpoints (/api/forms/*) are protected by server-side IP rate limiting (5 requests per 60 seconds). Agents must obtain explicit user consent before submitting these endpoints — each submission creates a real record with distillery staff.
Endpoints
Full OpenAPI 3.1 spec: /api/openapi.json.
| Method | Path | Description |
|---|---|---|
| GET | /api/facts.json | Core distillery facts — location, water source, production capacity. |
| GET | /api/products.json | Gin, whisky, and liqueur catalog as schema.org Product/Offer graph. |
| GET | /api/tour.json | Tour price, duration, languages, schedule, booking URLs. |
| GET | /api/pricing.json | Machine-readable pricing table for tour, gin SKUs, private casks. |
| GET | /api/press.json | Press kit index — logos, boilerplate, founder bios. |
| GET | /api/openapi.json | OpenAPI 3.1 spec for form submission endpoints. |
| POST | /api/forms/contact | General contact inquiry (rate-limited, user consent required). |
| POST | /api/forms/tour-booking | Distillery tour booking (rate-limited, user consent required). |
| POST | /api/forms/cask-inquiry | Private cask consultation request (rate-limited, user consent required). |
| POST | /api/forms/newsletter | Newsletter subscription (rate-limited). |
| POST | /api/forms/product-notify | Product notification signup (rate-limited). |
Markdown content negotiation
Every page on tankyudistillery.jp honours Accept: text/markdown via Netlify Edge middleware. The response body is our consolidated /llms-full.txt (~11 KB, comprehensive reference) with Content-Type: text/markdown; charset=utf-8 and Content-Signal: ai-train=yes, search=yes, ai-input=yes.
curl -sH "Accept: text/markdown" https://tankyudistillery.jp/ | head -40
Agent discovery surfaces
- /llms.txt — concise product summary with markdown links.
- /llms-full.txt — comprehensive distillery reference.
- /.well-known/ai-plugin.json — OpenAI-style plugin manifest.
- /.well-known/agent.json — generic agent discovery document.
- /.well-known/agent-card.json — A2A agent card.
- /.well-known/api-catalog — RFC 9727 linkset.
- /.well-known/mcp/server-card.json — SEP-1649 MCP server card.
- /.well-known/agent-skills/index.json — Agent Skills v0.2.0 index.
- /schemamap.xml — NLWeb Schema Map.
- /pricing.md — machine-readable pricing.
- /?mode=agent — stripped agent view of the homepage.
Content signals & crawl policy
Every response sets Content-Signal: ai-train=yes, search=yes, ai-input=yes. Per-bot overrides live in /robots.txt — for example, ChatGPT-User and PerplexityBot are allowed for search and input but excluded from training corpora, while Google Extended and Claude are allowed for training with our permission.
Code examples
bash
# Get the product catalogue
curl -s https://tankyudistillery.jp/api/products.json | jq '.["@graph"][].name'
# Submit a contact form (requires explicit user consent)
curl -X POST https://tankyudistillery.jp/api/forms/contact \
-H "Content-Type: application/json" \
-d '{"name":"Jane","email":"jane@example.com","subject":"Hello","message":"Hi","locale":"en"}'TypeScript (fetch)
type TourInfo = {
price: number
currency: string
duration: string
languages: string[]
bookingUrl: string
}
const res = await fetch('https://tankyudistillery.jp/api/tour.json', {
headers: { Accept: 'application/json' },
})
if (!res.ok) throw new Error(`Tankyu API error: ${res.status}`)
const tour: TourInfo = await res.json()
console.log(tour.price, tour.bookingUrl)Python
import requests
resp = requests.get(
"https://tankyudistillery.jp/api/facts.json",
headers={"Accept": "application/json"},
timeout=10,
)
resp.raise_for_status()
facts = resp.json()
print(facts["@graph"][0]["name"])Rate limits
Read-only JSON endpoints are CDN-cached for 24 hours and have no user-visible rate limit. Form POST endpoints are rate-limited to 5 requests per 60 seconds per IP. Exceeded limits return HTTP 429 with a JSON body:
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Please retry after the Retry-After window.",
"documentation_url": "https://tankyudistillery.jp/developers#rate-limits"
}
}Error responses
/api/* endpoints (both static JSON and form POSTs) return structured JSON on error, never HTML. Shape:
{
"error": {
"code": "validation_failed" | "not_found" | "rate_limited" | "internal_error",
"message": "human readable description",
"documentation_url": "https://tankyudistillery.jp/developers#errors",
"details": { /* optional per-field info */ }
}
}