Viewrium Docs

API reference

The full /v1 REST surface, request conventions, and how each endpoint maps to the SDKs.

The Viewrium API is a single JSON REST API. This page covers the conventions that apply everywhere and maps every /v1 endpoint to its SDK method. For request and response field definitions, the typed Python and JavaScript SDKs are generated from the same schema and are the most convenient reference.

Conventions

  • Base URL - https://api.viewrium.com. Every path below is relative to it.
  • Auth - Authorization: Bearer <key> on every request. See Authentication.
  • JSON - request and response bodies are JSON. Timestamps are ISO 8601 in UTC.
  • Pagination - list endpoints take limit and offset query params and return total, limit, and offset alongside data.
  • Scope - reads take org_id (or default to your only organization) and scope=all for every organization you reach. Writes always name one.
  • Repeated params - a filter that takes several values is repeated (?tag=a&tag=b), and tag_match (all | any) says how the repeats combine.
  • Errors - every non-2xx response is the envelope { "error": { "code", "message", "details" } }.

Endpoints

Products

MethodPathSDK
POST/v1/productsproducts.create
GET/v1/productsproducts.list
GET/v1/products/{id}products.retrieve
PATCH/v1/products/{id}products.update
DELETE/v1/products/{id}products.delete
DELETE/v1/products?ids=a&ids=bproducts.batchDelete / batch_delete
POST/v1/products/publishproducts.publish
GET/v1/products/tagsproducts.tags
GET/v1/products/exportproducts.export

POST /v1/products is the single entrypoint - supply exactly one of image_urls, video_url, source_url, model_url, image_paths, or resume_token. A fresh request answers 200 with a parked quote (nothing written); a resume_token or a model_url answers 202 with the created product. See How generation works.

GET /v1/products/{id} answers two shapes by principal: a session or sk_ key gets the product with its assets, a pk_ key gets the allow-listed public projection - and only for a published product with a ready model.

GET /v1/products/export answers a ZIP of finished images - each one composited onto its background with its shadow - selected by ids or by the list's own filters, at most 200 products. image_review_status (default accepted and pending) chooses which images go in; the archive's manifest.json names every entry and every image skipped. The 3D model is never included. When more images need finishing than one request can do, the answer is a 202 with status: "queued": they are finished in the background, a download link is emailed to notify_email, and the same request then streams the ZIP.

Assets and review

MethodPathSDK
PATCH/v1/products/{id}/images/{image_id}products.updateImage / update_image
PATCH/v1/products/{id}/modelproducts.updateModel / update_model
POST/v1/products/{id}/model/rescaleproducts.rescale
POST/v1/products/{id}/orderproducts.order
POST/v1/products/{id}/reviewproducts.review

POST /v1/products/{id}/order orders the missing half - images onto a model-only product, or a model onto an images one. It parks like a create: commit the returned token through products.create. A 409 carries details.reason (no_analysis, generating, images_ordered, model_exists, model_failed).

POST /v1/products/{id}/review is the batched flush: image decisions and settings, the model's decision, and the product's user-set status, validated together and applied in order. It records decisions only; the finished images are made by the export.

Analytics

MethodPathSDK
GET/v1/usageusage.get
POST/v1/beaconbeacon.send

GET /v1/usage takes an arbitrary window (start / end, defaulting to the last 30 days), granularity (hour | day), an event_type filter, and a scope: one organization (org_id), every one you reach (scope=all), or one product (product_id, which needs no org_id). Organization-internal traffic is excluded unless include_internal=true.

group_by=product additionally returns by_product: the window's best-performing products, ranked by 3D views then AR entries, capped at 20, each with its title. The buckets themselves are unchanged - to break one period down, ask again with the window narrowed to it. A subject with no product row is a v1 scan: it still counts in totals, but it is never a by_product row.

POST /v1/beacon accepts a publishable (pk_) key and is what the embed uses to report view / ar_enter / ar_session_ended events.

Webhooks

MethodPathSDK
GET/v1/webhookswebhooks.list
POST/v1/webhookswebhooks.create
GET/v1/webhooks/{id}webhooks.retrieve
PATCH/v1/webhooks/{id}webhooks.update
DELETE/v1/webhooks/{id}webhooks.delete
GET/v1/webhooks/{id}/deliverieswebhooks.listDeliveries / list_deliveries

See Webhooks for the event envelope and signature scheme.

Keys and projects

MethodPathSDK
GET/v1/api_keysapiKeys.list / api_keys.list
POST/v1/api_keysapiKeys.create / api_keys.create
DELETE/v1/api_keys/{id}apiKeys.revoke / api_keys.revoke
GET/v1/projectsprojects.list
GET/v1/projects/{id}projects.retrieve

Some management operations - creating API keys, for example - are restricted to account owners and admins and are typically done from the dashboard.

Health

MethodPathSDK
GET/v1/healthclient.health()

Key type access

Not every endpoint accepts every key type. In particular, publishable (pk_) keys are limited to GET /v1/products/{id} and POST /v1/beacon, and are origin-gated. Everything else requires a secret (sk_) key or a signed-in dashboard session. See Authentication for the full model.

Not on the public API

Organization, team and billing management, comments, change requests, and the review app's own tooling live on an internal surface that the dashboard uses and that is deliberately not part of /v1. The Viewrium Shopify app, which will sync products from a store, is coming soon.

On this page