Workflow
POST /api/v3/visual-readings/estimateto confirm availability and credits.- Create one private upload grant per image.
- Upload directly to the returned signed URL with the required headers.
- Complete each upload. AstroM8 validates the checksum and image, normalizes it to JPEG, removes metadata, and deletes the original object.
- Submit a job with an
Idempotency-Key. - Poll the job. Once complete, either follow the short-lived signed artifact URL or fetch validated JSON directly from
GET /api/v3/visual-readings/jobs/{jobId}/result.
purpose: "face". Palm jobs require two uploads with purpose: "palm_left" and purpose: "palm_right", plus capture-handedness metadata.
Image inputs are private and are never returned by the API. Normalized input objects are deleted after inference. Store the returned result artifact rather than its one-hour signed URL.
Structured result
The direct result endpoint returns one canonical Face or Palm object. It includes:observations: image-visible categories only, with optional per-signal confidence.quality: capture quality, coverage ratio, observed and omitted signals, and limitation codes.rule_hits: deterministic rule IDs and public-domain source page locators.dimensions: evidence-coverage percentages across six reading dimensions. These are not scores of the person.reading: localized cards and the cultural-reading notice.narrative: paragraphs grounded only in the listed rule IDs.provenance: provider/model plus method, schema, prompt, rules, narrative, and renderer versions.
dominant_hand and the submitted left/right capture mapping. A capture marked usable must cover at least half of the family schema; a usable Palm result must contain signals from both hands. Limited captures can return a partial result with explicit omitted signals.
409 while a job is incomplete or has no successful result, 404 for a job outside the credential owner, and a safe 503 if the private stored artifact fails validation. It never returns input images, storage object keys, or raw provider output.
Uploads are rejected before billing when their decoded image is undersized, unreadable, animated, very dark, blown out, flat, or too blurred for reliable visual analysis. These are non-semantic image-quality checks; they do not identify a face or hand.
Idempotency and credits
The job submission uses an atomic transaction: it reserves the idempotency key, verifies ownership and upload state, consumes the uploads, writes usage, and debits credits together. Retrying the same request with the same key replays its original job; a changed body with the same key returns a conflict. If the worker reaches a terminal failure, it refunds the remaining charged credits exactly once.json includes the structured result, branded adds private hosted HTML, and premium adds a private PDF. If premium PDF rendering fails after the JSON and branded artifacts succeed, the job remains usable and is refunded down to branded pricing.
Failed job responses expose a safe error_code such as provider_unavailable, provider_invalid_response, invalid_job_payload, or processing_failed; raw provider and infrastructure errors are not exposed.
Deletion
DELETE /api/v3/visual-readings/jobs/{jobId} removes a completed job and its private artifacts. A queued job is cancelled and fully refunded. An in-flight job returns 202 and is cancelled before it can publish an artifact; it is deleted once the worker has removed its normalized inputs.
Delivery
Dashboard customers can subscribe an HTTPS webhook or email destination through/v1/visual-reading-deliveries. Destinations are encrypted at rest and API responses show only a redacted hint.
Supported events are:
visual_reading.completedvisual_reading.failedvisual_reading.input_deleted
/v1/visual-reading-deliveries/events, and a terminally failed event can be requeued with /v1/visual-reading-deliveries/events/{id}/retry without rerunning or recharging the reading.