photoMedia
The photoMedia noun — identity, lifecycle, events, and every capability as an anchored section: 14 capabilities, 2 live, 12 sandbox, 0 declared.
photoMedia is one of the estate's 317 automotive nouns — a job a car needs done. It carries 14 capabilities: 2 live, 12 sandbox, 0 declared · doors aggregator.vin.
Identity
| Noun | photoMedia |
| Pillar | Services (facets: 5 data · 6 services · 3 commerce) |
| Capabilities | 14 — 2 live · 12 sandbox · 0 declared |
| Entities | Listing |
| Doors | aggregator.vin |
| SDK | Vin.photoMedia.* from apis.vin |
| Address | /catalog/photoMedia#{action} — the anchor IS the wire name minus photoMedia. |
Events
The vocabulary this noun can append to the record — 24 past-tense, versioned event types, each linked to the capability that emits it:
PhotoMedia.annotateRequested@1— emitted byannotatePhotoMedia.annotated@1— emitted byannotatePhotoMedia.backgroundSwapRequested@1— emitted bybackgroundSwapPhotoMedia.backgroundSwapped@1— emitted bybackgroundSwapPhotoMedia.captureFailed@1— emitted bycapturePhotoMedia.captureRequested@1— emitted bycapturePhotoMedia.captured@1— emitted bycapturePhotoMedia.classified@1— emitted byclassifyPhotoMedia.completed@1— emitted byorderPhotoMedia.damageDetected@1— emitted bydamageDetectPhotoMedia.dispatched@1— emitted byorderPhotoMedia.enhanceRequested@1— emitted byenhancePhotoMedia.enhanced@1— emitted byenhancePhotoMedia.ordered@1— emitted byorderPhotoMedia.paid@1— emitted bypayPhotoMedia.payFailed@1— emitted bypayPhotoMedia.payRequested@1— emitted bypayPhotoMedia.publishRequested@1— emitted bypublishPhotoMedia.published@1— emitted bypublishPhotoMedia.spin360Requested@1— emitted byspin360PhotoMedia.spin360ed@1— emitted byspin360PhotoMedia.subscribeRequested@1— emitted bysubscribePhotoMedia.subscribed@1— emitted bysubscribeServiceOrder.settled@1— emitted byorder
Discover & read
read
photoMedia.read · GET /photo-medias/read · gate none · live · answers PhotoMediaRead@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — live: answers on the wire today. A sandbox key still selects the deterministic simulated mode — drive the full outcome range with the magic triggers.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.read({"vin":"4S3BNAA62G3040768"})curl 'https://apis.vin/photo-medias/read?vin=4S3BNAA62G3040768'compare
photoMedia.compare · GET /photo-medias/compare · gate none · sandbox · answers PhotoMediaCompare@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.compare({"vin":"4S3BNAA62G3040768"})curl 'https://apis.vin/photo-medias/compare?vin=4S3BNAA62G3040768'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaCompare@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"comparison": {
"setId": "PH-14e49196",
"grade": "clean",
"consistent": true,
"basis": "condition-grade",
"damageShots": 0
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"comparison": {
"setId": "PH-14e49196",
"grade": "clean",
"consistent": true,
"basis": "condition-grade",
"damageShots": 0
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}classify
photoMedia.classify · GET /photo-medias/classify · gate key · sandbox · answers PhotoMediaClassify@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — PhotoMedia.classified@1.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.classify({"vin":"4S3BNAA62G3040768"})curl 'https://apis.vin/photo-medias/classify?vin=4S3BNAA62G3040768'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaClassify@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"classification": {
"setId": "PH-14e49196",
"byAngle": {
"exterior": 8,
"interior": 4,
"damage": 0
}
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"classification": {
"setId": "PH-14e49196",
"byAngle": {
"exterior": 8,
"interior": 4,
"damage": 0
}
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}damageDetect
photoMedia.damageDetect · GET /photo-medias/damage-detect · gate key · sandbox · answers PhotoMediaDamageDetect@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — PhotoMedia.damageDetected@1.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.damageDetect({"vin":"4S3BNAA62G3040768"})curl 'https://apis.vin/photo-medias/damage-detect?vin=4S3BNAA62G3040768'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaDamageDetect@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"damage": {
"found": false,
"count": 0,
"items": []
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"damage": {
"found": false,
"count": 0,
"items": []
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Apply & book
order
photoMedia.order · POST /photo-medias/order · gate offer · sandbox · answers PhotoMediaOrder@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — PhotoMedia.completed@1 · PhotoMedia.dispatched@1 · PhotoMedia.ordered@1 · ServiceOrder.settled@1.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.order({"vin":"4S3BNAA62G3040768"})curl -X POST https://apis.vin/photo-medias/order \
-H 'content-type: application/json' \
-d '{"vin":"4S3BNAA62G3040768"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaOrder@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"order": {
"id": "ORD-4e84e5a6",
"setId": "PH-14e49196",
"status": "placed",
"amountCents": 14900,
"currency": "USD"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"order": {
"id": "ORD-4e84e5a6",
"setId": "PH-14e49196",
"status": "placed",
"amountCents": 14900,
"currency": "USD"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}subscribe
photoMedia.subscribe · POST /photo-medias/subscribe · gate offer · sandbox · answers PhotoMediaSubscribe@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — PhotoMedia.subscribeRequested@1 · PhotoMedia.subscribed@1.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.subscribe({"vin":"4S3BNAA62G3040768"})curl -X POST https://apis.vin/photo-medias/subscribe \
-H 'content-type: application/json' \
-d '{"vin":"4S3BNAA62G3040768"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaSubscribe@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"subscription": {
"id": "PS-d72dd155",
"plan": "photo-media",
"amountCents": 24900,
"currency": "USD",
"status": "active"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"subscription": {
"id": "PS-d72dd155",
"plan": "photo-media",
"amountCents": 24900,
"currency": "USD",
"status": "active"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Pay & settle
pay
photoMedia.pay · POST /photo-medias/pay · gate offer · sandbox · answers PhotoMediaPay@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — PhotoMedia.paid@1 · PhotoMedia.payFailed@1 · PhotoMedia.payRequested@1.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.pay({"vin":"4S3BNAA62G3040768"})curl -X POST https://apis.vin/photo-medias/pay \
-H 'content-type: application/json' \
-d '{"vin":"4S3BNAA62G3040768"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaPay@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"payment": {
"id": "PAY-82da9968",
"status": "settled",
"amountCents": 14900,
"currency": "USD"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"payment": {
"id": "PAY-82da9968",
"status": "settled",
"amountCents": 14900,
"currency": "USD"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}capture
photoMedia.capture · POST /photo-medias/capture · gate offer · sandbox · answers PhotoMediaCapture@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — PhotoMedia.captureFailed@1 · PhotoMedia.captureRequested@1 · PhotoMedia.captured@1.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.capture({"vin":"4S3BNAA62G3040768"})curl -X POST https://apis.vin/photo-medias/capture \
-H 'content-type: application/json' \
-d '{"vin":"4S3BNAA62G3040768"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaCapture@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"set": {
"id": "PH-14e49196",
"status": "captured",
"shots": 12,
"plan": {
"exterior": 8,
"interior": 4,
"damage": 0
},
"grade": "clean"
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"set": {
"id": "PH-14e49196",
"status": "captured",
"shots": 12,
"plan": {
"exterior": 8,
"interior": 4,
"damage": 0
},
"grade": "clean"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Fulfill & operate
publish
photoMedia.publish · POST /photo-medias/publish · gate offer · sandbox · answers PhotoMediaPublish@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — PhotoMedia.publishRequested@1 · PhotoMedia.published@1.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.publish({"vin":"4S3BNAA62G3040768"})curl -X POST https://apis.vin/photo-medias/publish \
-H 'content-type: application/json' \
-d '{"vin":"4S3BNAA62G3040768"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaPublish@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"publication": {
"status": "published-to-listing",
"setId": "PH-14e49196",
"listingId": "LST-385c16c4",
"position": "Draft"
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"publication": {
"status": "published-to-listing",
"setId": "PH-14e49196",
"listingId": "LST-385c16c4",
"position": "Draft"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}annotate
photoMedia.annotate · POST /photo-medias/annotate · gate offer · sandbox · answers PhotoMediaAnnotate@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — PhotoMedia.annotateRequested@1 · PhotoMedia.annotated@1.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.annotate({"vin":"4S3BNAA62G3040768"})curl -X POST https://apis.vin/photo-medias/annotate \
-H 'content-type: application/json' \
-d '{"vin":"4S3BNAA62G3040768"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaAnnotate@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"annotation": {
"status": "no-damage-to-annotate",
"annotations": 0
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"annotation": {
"status": "no-damage-to-annotate",
"annotations": 0
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}More actions
backgroundSwap
photoMedia.backgroundSwap · POST /photo-medias/background-swap · gate offer · sandbox · answers PhotoMediaBackgroundSwap@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — PhotoMedia.backgroundSwapRequested@1 · PhotoMedia.backgroundSwapped@1.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.backgroundSwap({"vin":"4S3BNAA62G3040768"})curl -X POST https://apis.vin/photo-medias/background-swap \
-H 'content-type: application/json' \
-d '{"vin":"4S3BNAA62G3040768"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaBackgroundSwap@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"swap": {
"setId": "PH-14e49196",
"status": "swapped",
"background": "studio-neutral",
"shots": 8
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"swap": {
"setId": "PH-14e49196",
"status": "swapped",
"background": "studio-neutral",
"shots": 8
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}enhance
photoMedia.enhance · POST /photo-medias/enhance · gate offer · sandbox · answers PhotoMediaEnhance@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — PhotoMedia.enhanceRequested@1 · PhotoMedia.enhanced@1.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.enhance({"vin":"4S3BNAA62G3040768"})curl -X POST https://apis.vin/photo-medias/enhance \
-H 'content-type: application/json' \
-d '{"vin":"4S3BNAA62G3040768"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaEnhance@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"enhancement": {
"setId": "PH-14e49196",
"status": "enhanced",
"shots": 12
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"enhancement": {
"setId": "PH-14e49196",
"status": "enhanced",
"shots": 12
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}metadata
photoMedia.metadata · GET /photo-medias/metadata · gate none · live · answers PhotoMediaMetadata@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — live: answers on the wire today. A sandbox key still selects the deterministic simulated mode — drive the full outcome range with the magic triggers.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.metadata({"vin":"4S3BNAA62G3040768"})curl 'https://apis.vin/photo-medias/metadata?vin=4S3BNAA62G3040768'spin360
photoMedia.spin360 · POST /photo-medias/spin360 · gate offer · sandbox · answers PhotoMediaSpin360@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /4S3BNAA62G3040768 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — PhotoMedia.spin360Requested@1 · PhotoMedia.spin360ed@1.
import { photoMedia } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await photoMedia.spin360({"vin":"4S3BNAA62G3040768"})curl -X POST https://apis.vin/photo-medias/spin360 \
-H 'content-type: application/json' \
-d '{"vin":"4S3BNAA62G3040768"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "PhotoMediaSpin360@1",
"value": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"spin": {
"id": "SPIN-cab1574e",
"status": "captured",
"frames": 36
}
},
"evidence": {
"vin": "4S3BNAA62G3040768",
"noun": "photoMedia",
"asOf": "2026-08-10",
"spin": {
"id": "SPIN-cab1574e",
"status": "captured",
"frames": 36
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "curb-appeal-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Data model
The record shape behind this noun — one entity, each property an evidence field. See the whole estate model on the data model page.
Listing
Modeled
The noun drawn out — its record shape, its lifecycle, and how it is exercised end to end. 2 diagrams, rendered from the estate model.
PhotoMedia · Class model
PhotoMedia · State machine
Generated from the catalog. Every capability, answer, gate, and entity on this page is a rendered descriptor — it cannot drift from the wire.