EarthWonders API for developers
Keep your dealer inventory in sync without retyping it. Send specimens to EarthWonders in batches — one request per upload — and our pipeline resolves species, pulls locality and measurements out of your descriptions, processes your images and publishes the listings.
Last updated
How it works
- 1
Submit a batch
POST /batchSend your specimens as a single JSON payload. Only name is required per entry — everything else is optional and enriches the listing. The response returns a batchId.
- 2
Poll the batch status
GET /batch/{batchId}Check back until status leaves Uploading, Scheduled or Processing and settles on Finished, Failed or Archived.
- 3
Read the errors, if any
GET /batch/{batchId}/errorsReturns per-entry failures — an unresolvable species, a missing publishable image, or a malformed field — so you can correct and resubmit.
curl -X POST https://ingestion.earthwonders.com/batch \
-H "X-API-Key: $EARTHWONDERS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entries": [
{
"sourceKey": "SKU-10432",
"name": "Pink Fluorite on Albite",
"description": "5.2 x 3.1 x 2.4 cm, 84 g. Chumar Bakhoor, Gilgit-Baltistan, Pakistan.",
"sku": "SKU-10432",
"forSale": true,
"price": 450,
"currency": "USD",
"media": [
{ "url": "https://example.com/photos/10432-a.jpg", "sourceURLType": "FileLink" }
]
}
]
}'Authentication & keys
Every call carries your key in an X-API-Key header. Keys are issued by the EarthWonders team — tell us which store or collection you're integrating and we'll send one over.
Limits & fair use
5 requests per minute, per API key
Requests beyond that return 429 Too Many Requests without queueing — wait for the next minute window. Batching is the way to stay well under the limit: one POST /batch carries your whole upload, and a status poll every minute is plenty.
Up to 500 MB per request
A single batch payload can be up to 500 MB of JSON — thousands of entries. Media isn't uploaded in the request; you pass URLs and the pipeline fetches them.
Unique sourceKey per batch
Two entries with the same sourceKey in one batch are rejected. Across batches, reusing a sourceKey is the point — it updates the same specimen.
Public HTTPS media only
Media URLs must be publicly reachable over HTTPS — private hosts, plain HTTP, and login-gated links are rejected. YouTube and Vimeo links are supported via sourceURLType.
Species must be resolvable
Entries whose species can't be matched from the species array or inferred from the name are rejected rather than published as guesses.
Server-side calls only
The API has no browser CORS policy — call it from your backend or scripts, never from client-side code, and keep your key out of anything you ship to users.
What the pipeline fills in for you
- Species inferred from the specimen name when you don't send one — entries with no resolvable species are rejected rather than guessed.
- Locality, weight and size extracted from your free-text description.
- Dominant colors detected from the first image.
- Media fetched and processed into our CDN renditions; at least one publishable public HTTPS image is required to publish.
- Recurring uploads deduplicated by sourceKey — a stable key updates the existing specimen instead of creating a duplicate.
Quick start
Sample integration
A Node 20+ CLI that reads a CSV, posts one batch, polls until it settles and prints per-entry status and errors. Its typed client is generated from the schema with swagger-typescript-api.
View on GitHubOpenAPI schema
The full OpenAPI 3 document, served from earthwonders.com. Point swagger-typescript-api (or your generator of choice) at it to produce a typed client in your own stack.
openapi.jsonAPI reference
Every endpoint, field and enum — generated from the live OpenAPI document, with request and response examples in your language of choice.