How it works
Your data stays yours and your catalogue is authoritative. You send records matching the schema below. We never ask for your spreadsheet, your collection management system, or a migration project.
Everything arrives as a draft. Nothing becomes public until someone at your institution reviews and publishes it.
- Validate your mapping with
dry_run— no account needed. - Get an API key from us.
- Request upload URLs and send images straight to storage.
- Publish records in batches of up to 500.
- Review and publish from your dashboard.
Start without an account
A dry run validates records and writes nothing, so you can get the mapping right before you talk to us at all.
curl -X POST https://www.artheonmuseum.org/api/v1/publish -H "Content-Type: application/json" -d '{"dry_run": true, "records": [ ... ]}'Problems come back per record, naming the field, a stable code, what we received, and what was expected:
{
"index": 47,
"external_id": "1998.45",
"ok": false,
"errors": [{
"field": "date.start_year",
"code": "unparseable",
"message": "date.start_year must be a whole year as a number. Leave it out if the date is unknown and keep the original text in date.text.",
"got": "n.d."
}]
}A record
Three things are required: external_id, title, and rights.license. Everything else is optional. A sparse record is normal, and far better than an invented one.
{
"external_id": "1971.86.11",
"title": "Les Amoureux de Paris",
"title_lang": "fr",
"artist": { "display": "Robert Delaunay", "birth_year": 1885, "death_year": 1941 },
"date": { "text": "1928", "start_year": 1928, "end_year": 1928 },
"medium": "color lithograph",
"dimensions": { "text": "23 x 45 cm", "height_cm": 23, "width_cm": 45 },
"classification": "Print",
"department": "Modern Prints",
"identifiers": { "wikidata": "Q28100129" },
"credit_line": "Gift of Mr. and Mrs. Burton Tremaine",
"rights": {
"license": "public-domain",
"holder": "National Gallery of Art, Washington, D.C.",
"source_url": "https://www.nga.gov/collection/art-object-page.53045.html"
},
"images": [{ "key": "publishers/<your-id>/<uuid>-1971.86.11.tif", "role": "primary" }]
}The full field list and vocabularies are served as JSON at /api/v1/schema, so your tooling can read them instead of hardcoding them.
external_id is permanent
This is your own accession number, and it is how we recognise a record you have sent before. Publishing the same external_id again updates that record rather than creating a second one, so a re-run after a failure is safe. It also means changing an external_id later orphans the original and creates a duplicate. Choose something stable.
Licensing
rights.license is required and never inferred. Age does not imply public domain, and a museum photograph of a public-domain painting may itself be restricted. If you are unsure, use all-rights-reserved and leave the records as drafts. That is recoverable; publishing under the wrong licence is not.
public-domaincc0cc-bycc-by-sacc-by-ndcc-by-nccc-by-nc-sacc-by-nc-ndall-rights-reservedDates that are not simple
Keep your own string in date.text exactly as written. Set numeric years only when you can parse them confidently, and omit them when the date is genuinely unknown.
- Circa.
c. 1650becomesstart_year: 1645, end_year: 1655, circa: true. - BCE years are negative. Many systems store
1550–1196 BCas positive 1550 and 1196, which reads as a date running backwards. Use-1550to-1196. - Reproductions are not ranges. A 1903 reproduction of a 1790 print is not a 113-year span. The object is 1903; 1790 goes in
date.original_year. - Unknown. Keep the text, omit both years.
Images and 3D models
Ask for upload URLs, then send files straight to storage. They never pass through our servers, so a folder of large TIFFs is not a problem.
curl -X POST https://www.artheonmuseum.org/api/v1/uploads -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" -d '{"files": [{"filename": "1998.45.tif", "content_type": "image/tiff", "size": 41234567}]}'Then PUT each file to its returned upload_url with the same content type you declared, and use the returned key in the record:
curl -X PUT "UPLOAD_URL_FROM_RESPONSE" -H "Content-Type: image/tiff" --data-binary @1998.45.tifURLs expire after an hour, so request them in batches as you upload. Accepted types are JPEG, PNG, TIFF, WebP, AVIF and glTF/GLB, up to 512 MB per file. Uploading is not publishing — a file nothing references is simply unused.
Publishing
curl -X POST https://www.artheonmuseum.org/api/v1/publish -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" -d '{"records": [ ... ]}'Up to 500 records per request. A batch is all-or-nothing: if any record is invalid, nothing is written, so you can fix and resend without wondering what got through. The response reports how many were created and how many updated.
Verification
A verified publisher sits at the same level as any other institution on Artheon. There is no second tier for material that arrived through this API. Verification claims one thing only: that the account belongs to the named institution. It is not a claim about the authenticity or attribution of any individual work, which remains your scholarship and your credit.
Using an AI assistant
If your data is in spreadsheets with images in folders, an assistant can do the mapping. We publish a skill that walks it through profiling your columns, matching images to records, normalising dates and dimensions, and running the dry-run loop until it is clean. It runs on your machine, so your files stay under your control until you choose to publish.
Getting a key
Write to [email protected] with your institution and roughly how large the collection is. Keys are scoped to your organisation and can be revoked at any time. Until then, you can validate everything with dry_run.