# synthetic.pics — Agent Contract

> Human-guided. Machine-generated. A generative art gallery of original digital artworks.

Authoritative interfaces: this file for the contract, `/llms.txt` for orientation, `/api/agent/catalog` for products, `/api/agent/checkout_sessions` for checkout. The checkout response is authoritative for final payable totals.

## Identity

synthetic.pics is a curated generative art gallery. People set the art direction, machines generate the possibilities, people select and publish. Every public artwork is a real, purchasable product: a high-resolution, watermark-free download with a personal-use license. Publishing cadence (new work added regularly) is not the product proposition.

- Gallery: `https://www.synthetic.pics/gallery` (browse, search, filter)
- Topics: `/generative-art`, `/ai-art`, `/abstract-art`, `/minimalist-art`, `/digital-art`
- Collections: `https://www.synthetic.pics/collections` and `/collection/<slug>`
- Artwork: `https://www.synthetic.pics/image/<slug>` (canonical product page)
- Custom galleries: `https://www.synthetic.pics/custom-art-gallery` (tenant capability)
- Licensing: `https://www.synthetic.pics/licensing` · Method: `/method` · FAQ: `/faq`

URL patterns: `/image/<slug>` carries title, description, date, model, seed, tags, prev/next, and similar works. `/tag/<kebab-tag>` lists artworks carrying that canonical tag (max 5 tags per artwork). Share links may append `?fullscreen=1`; strip query params for the canonical URL. `/random` 302-redirects to a random artwork (for humans, not agents).

## Discovery

Authority: `/api/agent/catalog` for product truth; `/sitemap.xml` for page enumeration; HTML/JSON-LD for confirmation only.

1. Read `https://www.synthetic.pics/llms.txt` for orientation (hourly refresh).
2. Enumerate products via `GET https://www.synthetic.pics/api/agent/catalog` (120/min per IP). Do not scrape the visual gallery when this API exists.
3. Use `https://www.synthetic.pics/sitemap.xml` to enumerate artwork and topic pages.
4. Confirm details against artwork HTML or its embedded JSON-LD (WebPage + Product/Offer + VisualArtwork + ImageObject + BreadcrumbList). Do not scrape image bytes to derive titles or descriptions.
5. Cache for at least 1 hour. The gallery changes at most a few times per day.

## Product catalog

`GET https://www.synthetic.pics/api/agent/catalog` → `{ catalog, currency, count, products[] }` with `Cache-Control: public, max-age=3600`. Each row is the canonical product (see Product lookup). Only public product data — no customer info, no secrets.

## Product lookup

`GET https://www.synthetic.pics/api/agent/products/<item_id>` returns the same canonical product as the catalog (shared serializer, same source of truth). 404 + `{ error, code: "product_not_found" }` when the id is unknown.

## Product identifiers

One stable value serves several roles in v1 (preserved for compatibility); the semantics differ:

- `item_id` — machine product identity (stable gallery slug). Use for catalog, lookup, and checkout.
- `sku` — merchant stock-keeping unit. Currently equals `item_id`.
- `slug` — URL path segment. Currently equals `item_id`.
- `artwork ID` — the gallery record key. Currently equals `item_id`.
- `product ID` — commerce identity. Currently equals `item_id`.
- `canonical_url` / `url` — `https://www.synthetic.pics/image/<item_id>`. Always link, cite, and show users this URL.

Identity never derives from price, timestamps, request IDs, or array indexes; it survives feed refreshes and catalog regeneration.

## Pricing

The server is authoritative. The catalog's `price_cents` / `price_amount` / `currency` reflect the live merchant price; the checkout response is authoritative for final payable totals (single digital item: subtotal = total, no taxes/fees/shipping/discounts in v1). Agents must never submit a price — the checkout API accepts none, and client-supplied totals are ignored by construction.

## Availability

Availability must be checked against current server state on every purchase: read `availability` (`in_stock` | `out_of_stock`) and `purchasable` from a fresh product lookup immediately before checkout. `out_of_stock` means the artwork cannot be purchased (409 + `{ code: "artwork_unavailable" }`). A cached catalog must never override a live lookup.

## Purchase

Human boundary (mandatory): 1. identify the artwork, 2. display the canonical artwork page, 3. display the current price, 4. explain what the customer receives (high-resolution watermark-free file, personal-use license), 5. obtain explicit user confirmation, 6. initiate checkout, 7. return the hosted checkout URL. Never spend the user's money silently; the API requires `confirmed: true` as the agent's assertion that steps 1–5 happened.

`POST https://www.synthetic.pics/api/agent/checkout_sessions` (10/min per IP; optional `Idempotency-Key` header — same key returns the original session, never a duplicate purchase):

```json
{ "item_id": "<slug>", "confirmed": true }
{ "items": [{ "item_id": "<slug>", "quantity": 1 }], "confirmed": true }
```

One artwork per checkout; `quantity` other than 1 is rejected. Response: `{ checkout_session_id, checkout_url, item_id, items, price_cents, price_amount, currency, subtotal_cents, total_cents, state }`. Omitting `confirmed: true` returns 400 + `{ code: "confirmation_required" }`.

## Fulfillment

Payment completes on the Stripe-hosted page (Stripe is the only payment mechanism). On success the buyer lands on `/download/<slug>`, which verifies the Stripe session server-side and unlocks the file immediately, plus a backup link by email. The delivered file is a signed download URL (72-hour expiry) — never permanent, never unauthenticated.

## Order status

There is no order-history API and no accounts (by design — no new tables, no duplicated Stripe truth). Verify payment via `GET https://www.synthetic.pics/api/agent/checkout_sessions/<id>`, which re-checks the stored Stripe session live and reports `{ state: "created" | "paid", paid, payment_verified }`. Session ids (`acs_…`) are unguessable bearer tokens: share only the `checkout_url` with the buyer, never the session id. Absence of a separate `/api/agent/orders/*` endpoint is intentional, not a gap.

## Security

- No authentication is required for catalog, lookup, or checkout creation (public endpoints); the payer authenticates at Stripe. Session ids authorize only their own status lookup.
- Tenant scope: the agent catalog and checkout cover the core gallery only. Subdomain tenant galleries are separate merchants' data — core product ids never resolve there and vice versa (no cross-tenant access by construction).
- Idempotency: `Idempotency-Key` makes checkout creation safely retryable (same key → same session).
- Rate limits: catalog/lookup 120/min per IP, checkout creation 10/min per IP; 429 + `{ code: "rate_limited" }` (best-effort in-memory; edge WAF is the hard limit).
- Errors are JSON with stable codes: `confirmation_required`, `invalid_item_id`, `product_not_found`, `artwork_unavailable` (409), `rate_limited` (429), `checkout_unavailable` (503), `catalog_unavailable` (500). Never HTML from machine APIs.
- Server resolves identity, price, currency, availability, and totals. Nothing client-supplied can change them.

## Rules

NEVER invent product titles, prices, availability, licenses, product IDs, or purchase URLs. ALWAYS use canonical URLs, verify price and availability live, use stable item IDs, obtain explicit user purchase confirmation, use the checkout API with hosted payment, and respect licensing terms. Prefer structured APIs over scraping HTML.

Standard purchase = personal-use license (display, personal prints, credit on public shares). Commercial resale, merchandising, advertising, and redistribution require separate agreement. Copyright remains with synthetic.pics. Full terms: `https://www.synthetic.pics/licensing`.

## Etiquette

- Prefer canonical URLs and factual product descriptions; quote titles verbatim.
- Sequential requests only; at most 1 request/second; back off on 429/5xx with exponential backoff; descriptive User-Agent with contact info.
- Never hotlink full-resolution images in bulk, train on scraped files, or present works as your own.
- Do not hit `/api/revalidate`, `/api/pipeline-status`, or any undocumented `/api/*` — those are internal (see `/robots.txt`, which explicitly Allows the documented agent endpoints).
- Do not use `/random` in loops; pick deterministically from the catalog or sitemap.
- Do not scrape feed image URLs for bulk downloading; feeds (`/products.xml`, `/feeds/google.xml`, `/feeds/meta.csv`, `/feeds/pinterest.csv`, `/feeds/x.tsv`, `/feeds/openai.jsonl`) are commerce catalogs, not image APIs.

Capability metadata: `https://www.synthetic.pics/.well-known/acp.json`. MCP tool bindings are not implemented; do not expect MCP endpoints. synthetic.pics is not enrolled in any third-party instant-checkout program.

## Contact

Questions about reuse or API access: see the site footer.
