Edit models and file revisions
Rename, resize or replace a model without changing its ID.
Choose the operation
| Operation | File revision | Checks and pricing |
|---|---|---|
| Rename | Unchanged | No reprocessing. |
| Resize saved model | Unchanged | Rerun mesh integrity; refresh measurements, printability, preview and prices. |
| Replace file | New revision, same model ID | Restart inspection, preview and pricing; previous sources are retained. |
Use models:read for current state and history, models:write for edits, and files:write for replacement uploads. Names and sizes are current settings, not historical file versions. Accepted orders retain their original source and terms.
Rename or resize safely
GET the model and save its ETag response header as MODEL_ETAG, including the quotes. Send it in If-Match to protect the edit from concurrent changes. Save one of these bodies as model-update.json. Supply name, longest_dimension_mm, or both. Names must be nonblank; sizes are 30–200 mm. Without If-Match, the last write wins.
Rename body
json
{
"name": "Wedding figurine"
}Resize body
json
{
"longest_dimension_mm": 120
}Update a model
bash
# Requires models:write. GET the model with models:read and save its ETag header.
# Save only the intended name/size changes in model-update.json.
: "${MODEL_ETAG:?Set the saved ETag, including its quotes}"
curl --fail-with-body --max-time 30 --request PATCH \
"${API_BASE_URL%/}/api/v1/models/$MODEL_ID" \
--header "Authorization: Bearer $OTTOMFG_API_KEY" \
--header "If-Match: $MODEL_ETAG" \
--header "Content-Type: application/json" \
--data-binary @model-update.json
# On 412 precondition_failed, GET and compare before preparing another edit.
# After a timeout, read the model to reconcile; never refresh If-Match blindly.
Resize waits for active model processing to finish. It clears previous checks and pricing inputs, then reruns mesh inspection at the new size because inspection uses millimeter tolerances. Wait for fresh mesh_check, measurements and print_check; request new prices/quotes afterward. File revision and paid repair coverage stay unchanged. After terminal failure, retry PATCH at the same or a different size without uploading again. A failed resize cannot approve the new size.
PATCH has no idempotency-key replay. After a lost response, GET and compare the intended fields. A 412 precondition_failed means the ETag is stale; retrieve the model and review current state before using a new ETag. Do not blindly overwrite it in a retry loop.
Creation, replacement and resize share a per-account processing limit, including retries of failed models. Renames, no-op size saves and accepted idempotent replays do not consume it. On 429 resource_exhausted, wait for Retry-After (60 seconds), then GET current state before retrying an edit.
Upload a replacement
Register and upload a new same-account file. GET the target model and save the body below as model-replacement.json with real values. Save REVISION_REQUEST_KEY before sending. The replacement keeps the name and saved size, increments file_revision, and resets inspection and pricing.
Replacement body
json
{
"source": {
"file_id": "file_6c82bd3e319b4bb099310d54a761879e"
}
}Replace a model file
bash
# Requires models:write; upload the replacement first using files:write.
# Save only source.file_id in model-replacement.json; GET the model's ETag.
# Save REVISION_REQUEST_KEY once per intended replacement, before sending.
: "${MODEL_ETAG:?Set the saved ETag, including its quotes}"
: "${REVISION_REQUEST_KEY:?Set a saved key for this replacement}"
curl --fail-with-body --max-time 30 --request POST \
"${API_BASE_URL%/}/api/v1/models/$MODEL_ID/revisions" \
--header "Authorization: Bearer $OTTOMFG_API_KEY" \
--header "If-Match: $MODEL_ETAG" \
--header "Idempotency-Key: $REVISION_REQUEST_KEY" \
--header "Content-Type: application/json" \
--data-binary @model-replacement.json
# Retry the saved key, body and ETag after a timeout, within 24 hours.
# A replay returns the original replacement response; GET for current state.
# A new request with a stale If-Match returns 412 precondition_failed.
Retry the exact saved body and key after a timeout. Replacement keys last 24 hours. A replay returns the original response with Idempotent-Replayed: true, even if a newer revision now exists. A changed body with that key returns 409 idempotency_key_reused. Use If-Match to guard the first attempt; it does not block a successful replay.
Read file history
List file revisions
bash
# Requires models:read. Newest first; 20 file revisions per page by default.
curl --fail-with-body --max-time 30 \
"${API_BASE_URL%/}/api/v1/models/$MODEL_ID/revisions" \
--header "Authorization: Bearer $OTTOMFG_API_KEY"
# While has_more is true, repeat with ?limit=20&cursor=<next_cursor>.
# Use the returned cursor; do not assume it is a page number.
History is newest first. Use limit from 1 to 100 (default 20). Pass next_cursor as cursor while has_more is true. Each entry includes number, source.file_id, filename, created_at and current. Use the current model’s file_revision for its active source. There is no dedicated restore endpoint; uploading an older file again creates a new revision, not a rollback or restored repair coverage.
API v1 preview