Printy3D

Reference

API reference

Every endpoint and schema of the public /v1 API, rendered from the OpenAPI 3.1.0 document (version 0.1.0).

  • Base URL: https://printy3d-api-staging.onrender.com. Authenticate with Authorization: Bearer p3d_… (keys); the scope each endpoint needs is named in its description.
  • Every error is a Problem; the codes are on Errors.
  • Download the document: openapi.json. It works with OpenAPI tooling and code generators.

Files#

List files#

GET/v1/filesBearer key

Requires files:read. Cursor pagination within this organization and key mode.

Parameters

NameInTypeNotes
cursorquerystring0–100 characters
limitqueryintegerdefault 201–100

Responses

  • 200 Successful Response — FilePage
  • 401 403 404 409 413 422 429 501 Problem (application/problem+json)

Create file#

POST/v1/filesBearer key

Requires files:write. Reserve an immutable upload of up to 10 MiB in any accepted format.

PUT the exact bytes to upload.url with the returned headers, then complete the upload; the API verifies size, SHA-256 and the file's contents before it becomes ready. Live uploads need an approved account. Larger files use POST /v1/files/resumable. Idempotency-Key replays for 24 hours return a renewed upload URL.

Parameters

NameInTypeNotes
Idempotency-Keyrequiredheaderstring1–255 characters

Request body required

CreateFile

Responses

  • 201 Successful Response — FileUpload
  • 401 403 404 409 413 422 429 501 Problem (application/problem+json)

Create resumable file#

POST/v1/files/resumableBearer key

Reserve a file larger than a simple upload allows, up to the plan's limit (at most 1 GiB).

Needs an approved account (or an internal storage grant). The answer is an S3 multipart upload: PUT each listed part to its URL (exact size, any order). Part URLs are capabilities: keep them private. Replay the same request with the same Idempotency-Key to resume or to renew URLs; parts already sent are kept (at most three new multipart starts per file, failed responses included). Complete assembles the parts and always queues background verification; poll the file until ready or rejected.

Parameters

NameInTypeNotes
Idempotency-Keyrequiredheaderstring1–255 characters

Request body required

CreateResumableFile

Responses

Get file#

GET/v1/files/{file_id}Bearer key

Requires files:read.

Parameters

NameInTypeNotes
file_idrequiredpathstring

Responses

  • 200 Successful Response — File
  • 401 403 404 409 413 422 429 501 Problem (application/problem+json)

Complete file#

POST/v1/files/{file_id}/completeBearer key

Requires files:write. Prefer: respond-async queues durable verification.

Poll GET /v1/files/{file_id} until ready or rejected before creating a job. Resumable uploads always complete asynchronously. Without the preference, bounded legacy uploads still complete synchronously. Repeated completion calls do not enqueue duplicate verification work.

Parameters

NameInTypeNotes
file_idrequiredpathstring
preferheaderstring0–200 characters

Responses

  • 200 Successful Response — File
  • 202 Verification queued; poll Location. — File
  • 401 403 404 409 413 422 429 501 Problem (application/problem+json)

Jobs#

List jobs#

GET/v1/jobsBearer key

Requires jobs:read. Cursor pagination within this organization and key mode.

Parameters

NameInTypeNotes
cursorquerystring0–100 characters
limitqueryintegerdefault 201–100

Responses

  • 200 Successful Response — JobPage
  • 401 403 404 409 413 422 429 501 Problem (application/problem+json)

Create job#

POST/v1/jobsBearer key

Requires jobs:write. Queue a job for a ready file.

Sandbox (test-key) jobs return explicitly simulated results and incur no charge. A live job holds its expected cost in credits and is charged its run time when it finishes (usage); 402 insufficient_credits names the required and available credits when the balance cannot cover the hold (GET /v1/balance). 503 capacity_exhausted (with Retry-After and a reason) means a live job cannot start now: no GPU for a GPU recipe (paused, spend_limit, no_gpu_available, controller_offline), or no Exact Check worker running for a cad_check (cad_unavailable); nothing is queued or held. 501 feature_unavailable when live work, the input's format or size, or a live cad_check (its CPU lane's build) is not enabled. While a live job waits, queue gives its position, estimated_start_at and the GPU fleet's capacity (null for a cad_check); a queued live job fails free (capacity_exhausted) after 10 minutes without GPU capacity (a cad_check: without an Exact Check worker) or 24 hours in the queue. The Idempotency-Key is required; a replay within 24 hours returns the job as it is now, with Idempotent-Replayed: true.

Parameters

NameInTypeNotes
Idempotency-Keyrequiredheaderstring1–255 characters

Request body required

CreateJob

Responses

  • 202 Successful Response — Job
  • 401 402 403 404 409 413 422 429 501 503 Problem (application/problem+json)

Get job#

GET/v1/jobs/{job_id}Bearer key

Requires jobs:read. Poll status; analysis is published only after trusted verification.

Parameters

NameInTypeNotes
job_idrequiredpathstring

Responses

  • 200 Successful Response — Job
  • 401 403 404 409 413 422 429 501 Problem (application/problem+json)

Cancel job#

POST/v1/jobs/{job_id}/cancelBearer key

Requires jobs:write. Fence the attempt; accepted cancellation prevents result publication.

Parameters

NameInTypeNotes
job_idrequiredpathstring

Responses

  • 200 Successful Response — Job
  • 401 403 404 409 413 422 429 501 Problem (application/problem+json)

Job evaluation#

GET/v1/jobs/{job_id}/evaluationBearer key

Requires jobs:read. Free: judge the stored measurements of a succeeded cad_check job against the limits table of this organization, without a new job. Without process every process and material is judged; process alone judges each of its materials; material needs a process. 409 when the job is not a succeeded cad_check or its stored measurements expired; 503 (with Retry-After) when the limits table cannot be read.

Parameters

NameInTypeNotes
job_idrequiredpathstring
processquerystring | null0–64 characters
materialquerystring | null0–64 characters
scalequerynumberdefault 1> 0
assembly_intentquery"separate" | "together"default "separate"
movingquerybooleandefault false

Responses

  • 200 Successful Response — EvaluationList
  • 401 403 404 409 413 422 429 501 503 Problem (application/problem+json)

Job events#

GET/v1/jobs/{job_id}/eventsBearer key

Requires jobs:read. Durable ordered events; pass next_after to resume polling.

Parameters

NameInTypeNotes
job_idrequiredpathstring
afterqueryintegerdefault 0≥ 0

Responses

  • 200 Successful Response — EventPage
  • 401 403 404 409 413 422 429 501 Problem (application/problem+json)

Exact Check limits#

Get technologies#

GET/v1/technologiesBearer key

Requires jobs:read. The limits per process and material that apply to this organization: the global table with the organization's own overrides merged over it. version changes whenever either changes; nothing stores it with a check, and each evaluation answers with the version it judged by (table_version). gap_floor_mm is the higher of the global floor and any floor set for this organization.

Responses

Webhooks#

List webhook endpoints#

GET/v1/webhook_endpointsBearer key

Requires webhooks:manage. Every endpoint of the organization of this key's mode, oldest first, without secrets. Not paged: an account holds at most 20 endpoints of each mode, and all of them are in data.

Responses

Create webhook endpoint#

POST/v1/webhook_endpointsBearer key

Requires webhooks:manage. Register an HTTPS address to be told when a cad_check job finishes (name it in notify.webhook_endpoint when creating the job). The endpoint belongs to the key's mode: only keys of that mode can list, name or delete it. An account holds at most 20 endpoints of each mode; registering another is 409 conflict (delete one first).

The address must be https on port 443 or 1024 to 65535, and resolve to public hosts only: private, loopback, link-local and other non-routable addresses are refused (422, with the same sentence whether or not the name resolves), and checked again at every delivery.

The response holds the signing secret; verify Printy3D-Signature: t=<unix>,v1=<hex> as HMAC-SHA256 of <t>.<raw body> under it, in constant time, and reject a t more than 300 seconds from your clock. The payload is {event, job_id, status} and nothing else; fetch the job for the rest. A delivery is attempted up to 5 times in all, 1 m, 5 m, 30 m and 2 h apart. With an Idempotency-Key (kept 24 hours), a retry returns the same endpoint and secret with Idempotent-Replayed: true instead of registering a second one.

Parameters

NameInTypeNotes
Idempotency-Keyheaderstring | null1–255 characters

Request body required

CreateWebhookEndpoint

Responses

Delete webhook endpoint#

DELETE/v1/webhook_endpoints/{endpoint_id}Bearer key

Requires webhooks:manage. An endpoint of this key's mode; deliveries still waiting for it are called off. One already being sent when the endpoint is deleted may still arrive.

Parameters

NameInTypeNotes
endpoint_idrequiredpathstring

Responses

  • 204 Successful Response
  • 401 403 404 422 429 501 Problem (application/problem+json)

Artifacts & exports#

Download#

GET/v1/artifacts/{artifact_id}/downloadBearer key

Requires artifacts:read. Return a temporary download URL; keep it confidential.

Parameters

NameInTypeNotes
artifact_idrequiredpathstring

Responses

  • 200 Successful Response — Transfer
  • 401 403 404 409 413 422 429 501 Problem (application/problem+json)

Artifacts#

GET/v1/jobs/{job_id}/artifactsBearer key

Requires artifacts:read. Empty until the entire result manifest has passed verification.

Parameters

NameInTypeNotes
job_idrequiredpathstring

Responses

  • 200 Successful Response — ArtifactList
  • 401 403 404 409 413 422 429 501 Problem (application/problem+json)

Create export#

POST/v1/jobs/{job_id}/exportsBearer key

Requires jobs:write. A succeeded job's mesh output in one format, every piece in it.

200 ready with the artifact when the job generated that format. Otherwise 202 converting: one conversion job (conversion_job_id) makes it on the GPU fleet and is charged like any convert job (credits held and charged; 402, 429 and 503 as for POST /v1/jobs). Asking again returns the same conversion, or starts a new one after a failure; poll GET /v1/jobs/{job_id}/exports/{format}. Test keys export only the formats a job generated (501 for a conversion).

Parameters

NameInTypeNotes
job_idrequiredpathstring

Request body required

CreateExport

Responses

  • 200 Successful Response — Export
  • 202 Accepted — Export
  • 401 402 403 404 409 413 422 429 501 503 Problem (application/problem+json)

Get export#

GET/v1/jobs/{job_id}/exports/{format}Bearer key

Requires artifacts:read. The export's state; 404 when it was never asked for.

Parameters

NameInTypeNotes
job_idrequiredpathstring
formatrequiredpath"glb" | "obj" | "3mf" | "stl" | "ply"

Responses

  • 200 Successful Response — Export
  • 401 403 404 409 413 422 429 501 Problem (application/problem+json)

Credits#

Get balance#

GET/v1/balanceBearer key

Requires usage:read. The organization's credits; 1 credit = 1 second of a job's run.

Live jobs hold credits when submitted and are charged their run time when they finish; test-mode jobs never change the balance. POST /v1/jobs answers 402 insufficient_credits when a live job's hold exceeds available_credits.

Responses

  • 200 Successful Response — Balance
  • 401 403 422 429 Problem (application/problem+json)

List transactions#

GET/v1/balance/transactionsBearer key

Requires usage:read. Every credit movement, newest first.

Parameters

NameInTypeNotes
beforequeryinteger | null≥ 1
limitqueryintegerdefault 201–100

Responses

Account, keys & catalogue#

List API keys#

GET/v1/api_keysBearer key

Requires keys:manage. Lists metadata in this organization and live/test mode.

Parameters

NameInTypeNotes
cursorquerystring | null0–100 characters
limitqueryintegerdefault 201–100

Responses

  • 200 Successful Response — ApiKeyPage
  • 401 403 404 409 422 429 Problem (application/problem+json)

Create API key#

POST/v1/api_keysBearer key

Requires keys:manage; scopes and restrictions cannot exceed the issuer.

Idempotency-Key is retained for 24 hours. Replays return issuance metadata with secret=null and Idempotent-Replayed=true; plaintext is returned once.

Parameters

NameInTypeNotes
Idempotency-Keyrequiredheaderstring1–255 characters

Request body required

CreateApiKey

Responses

  • 201 Successful Response — IssuedApiKey
  • 401 403 404 409 422 429 Problem (application/problem+json)

Get API key#

GET/v1/api_keys/{key_id}Bearer key

Requires keys:manage. Never returns a credential secret or its hash.

Parameters

NameInTypeNotes
key_idrequiredpathstring

Responses

  • 200 Successful Response — ApiKey
  • 401 403 404 409 422 429 Problem (application/problem+json)

Revoke API key#

DELETE/v1/api_keys/{key_id}Bearer key

Requires keys:manage. Repeated revocation of the same visible key is harmless.

Parameters

NameInTypeNotes
key_idrequiredpathstring

Responses

  • 204 Successful Response
  • 401 403 404 409 422 429 Problem (application/problem+json)

Rotate API key#

POST/v1/api_keys/{key_id}/rotateBearer key

Requires keys:manage. Creates one successor without broadening authority.

The old key works during its grace period unless expired or revoked. An idempotent replay returns metadata with secret=null. Retain a recovery manager when requesting zero-grace self-rotation.

Parameters

NameInTypeNotes
key_idrequiredpathstring
Idempotency-Keyrequiredheaderstring1–255 characters

Request body required

RotateApiKey

Responses

  • 201 Successful Response — IssuedApiKey
  • 401 403 404 409 422 429 Problem (application/problem+json)

List formats#

GET/v1/formatsBearer key

Requires files:read. enabled is live qualification; test_enabled is local sandbox support.

Responses

  • 200 Successful Response — FormatList
  • 401 403 404 409 422 429 Problem (application/problem+json)

Get organization#

GET/v1/orgBearer key

Requires org:read. Returns only the authenticated organization.

Responses

  • 200 Successful Response — Organization
  • 401 403 404 409 422 429 Problem (application/problem+json)

List repair profiles#

GET/v1/profilesBearer key

Requires files:read. The values each repair profile fixes; the rest is filled from the engine's recommendation (recommended) or the documented defaults.

Responses

Status#

Liveness#

GET/healthzNo auth

Liveness: the process is up. Never touches a dependency.

Responses

  • 200 Successful Response — any

Readiness#

GET/readyzNo auth

Check the migrated database, non-owner runtime role and local storage.

Redis is not required for the local sandbox. Hosted object storage is not probed here until staging qualifies it (render-platform.md §4).

Responses

  • 200 Successful Response — any

Schemas#

AnalysisApiKeyApiKeyPageAppliedRepairArtifactArtifactListBalanceCadCheckResultCapacityCreateApiKeyCreateExportCreateFileCreateJobCreateResumableFileCreateWebhookEndpointCreditTransactionCreditTransactionPageDataNoticeErrorCodeEvaluationEvaluationListEventPageExportFidelityReportFileFilePageFileUploadFindingFormatFormatKindFormatListIssuedApiKeyIssuedWebhookEndpointJobJobEventJobPageJobQueueJobUsageJsonValueNotifyTargetOrganizationProblemProblemFieldQualityAssessmentRecommendationAssessmentRepairIssueRepairParamsRepairProfileRepairProfileListRepairResultResumableFileUploadResumableUploadRotateApiKeyScaleScopeSizeBandSmoothingTechnologyRowTechnologyTableThicknessToolResultTransferUploadPartWebhookEndpointWebhookEndpointPage

Analysis#

FieldTypeNotes
appliedAppliedRepair | null
dimensions_mmrequired[number, number, number]at most 3 items
facesrequiredinteger> 0
fidelityFidelityReport
is_watertightrequiredboolean
recommendation_assessmentRecommendationAssessment | null
recommendation_assessments_by_scalemap<string, RecommendationAssessment> | null
recommendedRepairParams | null
recommended_by_scalemap<string, RepairParams> | null
schema_version"1"default "1"
shellsinteger | null≥ 0
simulatedrequiredboolean
surface_area_mm2requirednumber≥ 0
verticesrequiredinteger> 0
volume_mm3requirednumber≥ 0
warningsstring[]at most 100 items

ApiKey#

FieldTypeNotes
created_atrequiredstring (date-time)
expires_atrequiredstring (date-time) | null
grace_untilrequiredstring (date-time) | null
idrequiredstring
kindrequired"live" | "test"
last_used_atrequiredstring (date-time) | null
namerequiredstring
org_idrequiredstring
prefixrequiredstring
revoked_atrequiredstring (date-time) | null
scopesrequiredScope[]
superseded_byrequiredstring | null

ApiKeyPage#

FieldTypeNotes
datarequiredApiKey[]
next_cursorstring | null

AppliedRepair#

What the repair actually ran with, and where each value came from.

wall_thickness_applied_mm is the wall the engine pushed to, which is params.wall_thickness_mm unless the engine raised it: the wall is floored at four voxels of the fine grid (a 0.7 mm request became 1.46 mm on a 20-inch print) and clamped at 10 % of the longest axis (fact: PrepEngine.cpp wallThicknessAppliedMM / wallThicknessClamped). wall_thickness_clamped says whether it differs. Both are None when the engine did not report them (a sandbox that predates them).

FieldTypeNotes
diagnostic_overridesmap<string, integer | boolean>
effective_engine_settingsmap<string, JsonValue> | null
paramsrequiredRepairParams
sourcesrequiredmap<string, "explicit" | "printer" | "profile" | "recommended" | "default">
wall_thickness_applied_mmnumber | null≥ 0
wall_thickness_clampedboolean | null

Artifact#

FieldTypeNotes
idrequiredstring
job_idrequiredstring
labelrequiredstring
media_typerequiredstring
sha256requiredstring
size_bytesrequiredinteger

ArtifactList#

FieldTypeNotes
datarequiredArtifact[]

Balance#

The organization's credits. available = included + purchased - held.

Included credits come with the plan each period and expire at its end; purchased credits never expire and go negative when a job runs longer than its balance covered.

FieldTypeNotes
available_creditsrequiredinteger
exhaustedrequiredboolean
held_creditsrequiredinteger
included_creditsrequiredinteger
lowrequiredboolean
period_endrequiredstring (date-time)
period_startrequiredstring (date-time)
purchased_creditsrequiredinteger

CadCheckResult#

FieldTypeNotes
accuracy_mmrequirednumber
open_partsrequiredinteger
pairsrequiredinteger
partsrequiredinteger
placed_copiesrequiredinteger
sample_limit_per_shaperequiredinteger
schema_versionrequiredinteger
sheet_partsrequiredinteger
truncatedrequiredboolean
unsupported_placementsinteger | null

Placements in the file the checker could not read, so the parts they place were not measured. An evaluation reports them as PLACEMENTS_UNREAD. null for a file checked before 2026-11-10, whose checker did not count them.

Capacity#

FieldTypeNotes
reason"paused" | "spend_limit" | "no_gpu_available" | "controller_offline" | null
retry_after_sinteger | null
staterequired"available" | "busy" | "exhausted"

CreateApiKey#

FieldTypeNotes
expires_atstring (date-time) | null
namerequiredstring1–100 characters
scopesrequiredScope[]at most 10 items

CreateExport#

FieldTypeNotes
formatrequired"glb" | "obj" | "3mf" | "stl" | "ply"

CreateFile#

FieldTypeNotes
filenamerequiredstring5–200 characters
sha256requiredstringpattern ^[a-f0-9]{64}$
size_bytesrequiredinteger> 0, ≤ 10,485,760

CreateJob#

FieldTypeNotes
input_file_idrequiredstringpattern ^file_[0-9A-HJKMNP-TV-Z]{26}$
notifyNotifyTarget | null
paramsRepairParams | object | null
recipe"inspect" | "repair" | "tool" | "cad_check"default "inspect"
tool"measure" | "convert" | "cut" | "lattice" | "label" | "mirror" | "remove_small_parts" | "thickness" | "analyze" | "medial" | "structural.components" | "structural.fea" | "structural.heatmap" | "structural.fragility" | "structural.measure_all" | "structural.relief" | null

CreateResumableFile#

FieldTypeNotes
filenamerequiredstring5–200 characters
input_formatrequired"stl" | "obj" | "3mf" | "ply" | "wrl" | "vrm" | "fbx" | "gltf" | "glb" | "dae" | "off" | "dcm" | "dicom" | "las" | "laz" | "step" | "zip" | "tar" | "tgz" | "rar"
sha256requiredstringpattern ^[a-f0-9]{64}$
size_bytesrequiredinteger> 0, ≤ 1,073,741,824

CreateWebhookEndpoint#

An HTTPS address that resolves to a public host. Anything else is refused.

FieldTypeNotes
urlrequiredstring9–2048 characters

CreditTransaction#

FieldTypeNotes
available_afterrequiredinteger
created_atrequiredstring (date-time)
held_deltarequiredinteger
included_deltarequiredinteger
job_idstring | null
kindrequired"plan_grant" | "expire" | "topup" | "adjust" | "hold" | "settle"
notestring | null
purchased_deltarequiredinteger
sequencerequiredinteger

CreditTransactionPage#

Newest first; pass next_before as before for the next page.

FieldTypeNotes
datarequiredCreditTransaction[]
next_beforeinteger | null

DataNotice#

FieldTypeNotes
processing_regionrequiredstring
retention_daysrequiredinteger

ErrorCode#

Every code the API may emit, public plane and worker plane.

malformed_requestunauthenticatedinvalid_api_keybootstrap_invalidinsufficient_creditsinsufficient_scopeorg_requiredorigin_not_allowedip_not_allowedimage_not_allowedaccount_pendingnot_foundmethod_not_allowedconflictjob_not_cancellableidempotency_in_progresslease_expiredlease_terminalexpiredfile_too_largeunsupported_formatvalidation_failedidempotency_key_reusedinput_too_largecontracts_mismatchrate_limitedconcurrency_limitquota_exceededinternalfeature_unavailableservice_unavailablecapacity_exhausted

Evaluation#

FieldTypeNotes
findingsrequiredFinding[]
materialrequiredstring
processrequiredstring
summaryrequired"ok" | "warnings" | "blocked"

EvaluationList#

Verdicts for one stored check, and the version of the limits table they were judged by.

FieldTypeNotes
itemsrequiredEvaluation[]
table_versionrequiredinteger

EventPage#

FieldTypeNotes
datarequiredJobEvent[]
next_afterrequiredinteger

Export#

A job's mesh output in one format, every piece in it (ADR-0058).

ready: download artifact (GET /v1/artifacts/{id}/download). converting: the format was not generated, a conversion job (conversion_job_id, charged like any convert job) is making it; ask again. failed: error_code says why; creating the export again starts a new conversion.

FieldTypeNotes
artifactArtifact | null
conversion_job_idstring | null
error_codestring | null
formatrequired"glb" | "obj" | "3mf" | "stl" | "ply"
job_idrequiredstring
statusrequired"ready" | "converting" | "failed"

FidelityReport#

An artifact-bound comparison; absent or uncalibrated evidence never passes.

FieldTypeNotes
calibration_idstring | null0–200 characters
config_sha256string | nullpattern ^[a-f0-9]{64}$
coordinate_framestring | null0–100 characters
errorstring | null0–500 characters
input_sha256string | nullpattern ^[a-f0-9]{64}$
limitationsstring[]at most 100 items
method_versionstring | null0–100 characters
metricsmap<string, JsonValue>
output_sha256string | nullpattern ^[a-f0-9]{64}$
reason_codesstring[]at most 100 items
schema_version"1"default "1"
source_scope"original_input" | "engine_transformed_source"default "original_input"
source_sha256string | nullpattern ^[a-f0-9]{64}$
source_to_output_transformnumber[][] | null
status"not_assessed" | "needs_review" | "passed" | "failed"default "not_assessed"
thresholdsmap<string, JsonValue>
thresholds_calibratedbooleandefault false
transform_verifiedbooleandefault false

File#

FieldTypeNotes
created_atrequiredstring (date-time)
filenamerequiredstring
idrequiredstring
input_format"stl" | "obj" | "3mf" | "ply" | "wrl" | "vrm" | "fbx" | "gltf" | "glb" | "dae" | "off" | "dcm" | "dicom" | "las" | "laz" | "step" | "zip" | "tar" | "tgz" | "rar"default "stl"
kind"mesh" | "splat" | "pointcloud" | "medical" | "cad" | "archive"default "mesh"
livemoderequiredboolean
rejected_reasonstring | null
sha256requiredstring
size_bytesrequiredinteger
statusrequired"awaiting_upload" | "verifying" | "ready" | "rejected"

FilePage#

FieldTypeNotes
datarequiredFile[]
next_cursorstring | null

FileUpload#

FieldTypeNotes
filerequiredFile
uploadrequiredTransfer

Finding#

FieldTypeNotes
coderequiredstring
frame"part" | "assembly" | null

The frame of location: part (the shape's own frame, before it is placed; the point applies to every placed copy of the part) or assembly (the frame of the whole assembly). Null when location is null.

limit_mmrequirednumber | null
locationrequirednumber[] | null

A point in millimetres, or null. A wall, or a gap measured inside one body, is in that shape's own frame and applies to every placed copy of the part. A finding between two parts, or between two bodies of one part, is in the frame of the whole assembly. frame says which.

messagerequiredstring
partrequiredstring | null
severityrequired"information" | "warning" | "blocking"
value_mmrequirednumber | null

Format#

FieldTypeNotes
enabledrequiredboolean
extrequiredstring
kindrequiredFormatKind
test_enabledbooleandefault false

FormatKind#

formats.kind. Same members as FileKind; kept separate because the formats table describes an extension and a file describes an upload.

meshsplatpointcloudmedicalcadarchive

FormatList#

FieldTypeNotes
datarequiredFormat[]

IssuedApiKey#

FieldTypeNotes
api_keyrequiredApiKey
secretstring | null

IssuedWebhookEndpoint#

The only response that carries the signing secret.

FieldTypeNotes
created_atrequiredstring (date-time)
enabledrequiredboolean
idrequiredstring
livemoderequiredboolean

True when registered with a live key. An endpoint is told only about jobs of its own mode, and only keys of that mode can list, name or delete it.

secretrequiredstring
urlrequiredstring

Job#

FieldTypeNotes
analysisAnalysis | null
attemptrequiredinteger
created_atrequiredstring (date-time)
error_codestring | null
error_detailstring | null
idrequiredstring
input_file_idrequiredstring
livemoderequiredboolean
paramsobject | null
progressinteger | null
queueJobQueue | null
reciperequired"inspect" | "repair" | "tool" | "cad_check"
resultRepairResult | ToolResult | CadCheckResult | null
simulatedbooleandefault true
stagestring | null
statusrequired"queued" | "running" | "verifying" | "succeeded" | "failed" | "cancelled"
tool"measure" | "convert" | "cut" | "lattice" | "label" | "mirror" | "remove_small_parts" | "thickness" | "analyze" | "medial" | "structural.components" | "structural.fea" | "structural.heatmap" | "structural.fragility" | "structural.measure_all" | "structural.relief" | null
updated_atrequiredstring (date-time)
usageJobUsage | null

JobEvent#

FieldTypeNotes
created_atrequiredstring (date-time)
progressinteger | null
sequencerequiredinteger
stagestring | null
statusrequiredstring

JobPage#

FieldTypeNotes
datarequiredJob[]
next_cursorstring | null

JobQueue#

A queued live job's place. Refreshed every 30 s; a stale estimate is left out.

FieldTypeNotes
capacityCapacity | null
estimated_start_atstring (date-time) | null
positioninteger | null

JobUsage#

Credits of one live job: held at admission, charged once it finishes.

FieldTypeNotes
charge_basis"run_time" | "minimum" | "free" | null
charged_creditsinteger | null
held_creditsrequiredinteger

JsonValue#

any

NotifyTarget#

The registered endpoint to tell when the job finishes. Ad-hoc URLs are not accepted.

FieldTypeNotes
webhook_endpointrequiredstringpattern ^whe_[0-9A-HJKMNP-TV-Z]{26}$

Organization#

FieldTypeNotes
idrequiredstring
namerequiredstring
plan_idrequiredstring
statusrequired"active" | "suspended" | "deleting"

Problem#

The single error envelope (api.md §3.2).

model_config.extra = "allow" carries the code-specific extras — required and available on insufficient_credits, for instance — without a subclass per code.

FieldTypeNotes
coderequiredErrorCode
detailstring | null
errorsProblemField[]
instancestring | null
request_idstring | null
statusrequiredinteger
titlerequiredstring
typerequiredstring

ProblemField#

One field-level validation failure inside Problem.errors.

FieldTypeNotes
fieldrequiredstring
messagerequiredstring

QualityAssessment#

FieldTypeNotes
print_readiness"not_assessed"default "not_assessed"
reason_codesstring[]at most 100 items
status"not_assessed" | "needs_review" | "passed" | "failed"default "not_assessed"

RecommendationAssessment#

Source-wall prediction at one size, never a certificate of the repaired print.

FieldTypeNotes
clearance_basis"shell_count_heuristic" | "unavailable"default "unavailable"
measurement_confidence"unavailable" | "limited"default "unavailable"
open_surface_fractionnumber | null0–1
predicted_minimum_size_mmnumber | null> 0
processstring | null0–100 characters
reason_codesstring[]at most 100 items
source_below_wall_fractionnumber | null0–1
source_below_wall_fraction_lowernumber | null0–1
source_below_wall_fraction_uppernumber | null0–1
status"not_assessed" | "needs_review"default "not_assessed"
target_mmnumber | null> 0
verified_minimum_size_mmnumber | null> 0
wall_basis"unavailable" | "measured" | "percentile_interpolation"default "unavailable"
wall_floor_mmnumber | null> 0
wall_quantile_sizes_mmmap<string, number>

RepairIssue#

FieldTypeNotes
descriptionrequiredstring
fixedrequiredboolean
namerequiredstring
severityrequired"critical" | "warning" | "info"

RepairParams#

Bounds follow the 3D Prep Pro request schema kept for continuity (api.md §6).

FieldTypeNotes
clearance_mmnumberdefault 1.50–10
close_holes_mmnumberdefault 00–2000
cut_transparentbooleandefault false
hollow_mmnumberdefault 00–20
mix_texturesbooleandefault false
preserve_shellsbooleandefault false
printer"mimaki" | "fdm" | null
profile"recommended" | "character" | "mechanical" | "vehicle" | "custom"default "recommended"
quality"draft" | "standard" | "high"default "standard"
scaleScale
smoothingSmoothing
target_facesintegerdefault 00–5,000,000
thicknessThickness
wall_thickness_mmnumberdefault 10–10

RepairProfile#

FieldTypeNotes
descriptionrequiredstring
idrequired"recommended" | "character" | "mechanical" | "vehicle" | "custom"
paramsrequiredobject

RepairProfileList#

FieldTypeNotes
datarequiredRepairProfile[]

RepairResult#

Before/after comparison; shape follows the Windows worker's result document.

FieldTypeNotes
afterrequiredAnalysis
appliedAppliedRepair | null
beforerequiredAnalysis
improvementsstring[]at most 100 items
issuesRepairIssue[]at most 100 items
output_bytesrequiredinteger≥ 0
printability_scorerequiredinteger0–100
qualityQualityAssessment
schema_version"1"default "1"
simulatedrequiredboolean

ResumableFileUpload#

FieldTypeNotes
filerequiredFile
uploadrequiredResumableUpload

ResumableUpload#

An S3 multipart upload (api.md §4.1).

parts lists only the parts the store does not hold yet, each with its own URL. Send them in any order or in parallel, then complete the file. Replaying the request that created the file returns fresh URLs for the parts still missing; parts already sent are kept.

FieldTypeNotes
expires_atrequiredstring (date-time)
method"PUT"default "PUT"
part_size_bytesrequiredinteger
partsrequiredUploadPart[]
protocol"s3_multipart"default "s3_multipart"

RotateApiKey#

FieldTypeNotes
grace_secondsintegerdefault 864000–604,800

Scale#

FieldTypeNotes
mode"none" | "target" | "multiplier"default "none"
unit"mm" | "cm" | "in"default "mm"
valuenumber | null> 0, ≤ 10,000

Scope#

files:readfiles:writejobs:readjobs:writeartifacts:readwebhooks:managekeys:manageusage:readorg:readadmin:billing

SizeBand#

FieldTypeNotes
up_to_mmrequirednumber
wall_mmrequirednumber

Smoothing#

FieldTypeNotes
clrintegerdefault 00–256
post_constructintegerdefault 00–50
pre_smoothboolean | null

TechnologyRow#

FieldTypeNotes
gap_assembled_mmrequirednumber | null
gap_inside_mmrequirednumber | null
gap_moving_mmrequirednumber | null
hole_countrequiredinteger | null
hole_min_diameter_mmrequirednumber | null
interiorrequired"closed_ok" | "needs_holes" | "not_offered"
labelrequiredstring
materialrequiredstring
processrequiredstring
sourcerequiredstring
wall_by_sizeSizeBand[] | null
wall_min_mmrequirednumber | null

TechnologyTable#

FieldTypeNotes
gap_floor_mmrequirednumber
noticerequiredDataNotice
rowsrequiredTechnologyRow[]
versionrequiredinteger

Thickness#

The thickness stage's instrument (engine thicknessMethod, Settings.h) and its target.

medial measures every wall with the maximum inscribed ball (orientation- and curvature-invariant, engine MedialThickening), pushes the measured deficit along the caliper axis and caps it by the free room on each side; with structural on, the beam reduction raises the target on the shank of a thin feature that fails under tip_load_n at target_sf. lattice is the voxel heatmap the 3D Prep Pro pipeline ships. The tip load is the constant the coupon matrix has not measured (engine docs/medial-axis.md §6): it is echoed on every result and never a hidden default.

FieldTypeNotes
method"medial" | "lattice"default "medial"
structuralbooleandefault true
target_sfnumberdefault 21–10
tip_load_nnumberdefault 0.5> 0, ≤ 50

ToolResult#

The engine's stdout envelope result object, path keys removed by the worker.

FieldTypeNotes
resultrequiredobject
schema_version"1"default "1"
simulatedrequiredboolean
toolrequired"measure" | "convert" | "cut" | "lattice" | "label" | "mirror" | "remove_small_parts" | "thickness" | "analyze" | "medial" | "structural.components" | "structural.fea" | "structural.heatmap" | "structural.fragility" | "structural.measure_all" | "structural.relief"

Transfer#

FieldTypeNotes
expires_atrequiredstring (date-time)
headersmap<string, string>
methodrequired"GET" | "PUT"
urlrequiredstring

UploadPart#

One part of a multipart upload: PUT exactly size_bytes from offset to url.

FieldTypeNotes
offsetrequiredinteger≥ 0
part_numberrequiredinteger1–10,000
size_bytesrequiredinteger> 0
urlrequiredstring

WebhookEndpoint#

FieldTypeNotes
created_atrequiredstring (date-time)
enabledrequiredboolean
idrequiredstring
livemoderequiredboolean

True when registered with a live key. An endpoint is told only about jobs of its own mode, and only keys of that mode can list, name or delete it.

urlrequiredstring

WebhookEndpointPage#

FieldTypeNotes
datarequiredWebhookEndpoint[]

Every endpoint of the key's mode, oldest first. The list is not paged: an account holds at most 20 endpoints of each mode.