The quote object
A price for printing one model file. Integrators upload model files to get quotes; until the account is approved, 10 approved quotes are also what 3DAPI reviews to approve the account (see get_integrator_onboarding).
Attributes
- idstring
Unique identifier of the quote, prefixed with
qte_. Treat it as an opaque string: store it and compare it, never parse it. - objectstring
Names the type of this object. Always
quote. - namestring
Display name of the quote. The
nameyou sent when creating it, otherwise the uploaded file name. - fileobject
The model file you uploaded, exactly as you sent it, and the production version 3DAPI prepared from it.
- statusQuoteStatus
Where the quote stands:
processing: the file is being sliced to measure material and print time. Usually takes one to a few minutes.ready: slicing finished andpriceis set.failed: the file could not be sliced, for example a broken or empty model.failure_reasonsays why. Upload a corrected file as a new quote.
Possible valuesprocessingreadyfailed - priceobject or null
Price to print one unit of the model, in usd: the price of the file that gets printed, which is
file.production_versionwhen there is one, otherwise your upload. Null untilstatusisready, and on failed quotes. - failure_reasonstring or null
Why slicing failed, written to be shown to a person, usually with how to fix the file. For example, a binary STL the slicer cannot read (small models exported with zero normals are mistaken for text STL files) says to export it again with normals or as .3mf. Null unless
statusisfailed. What a printable file needs: https://public-api.dapi.digital/docs/guides/file-requirements. - suggested_materialsarray of SuggestedMaterial or null
One suggested catalog material per extruder slot the file prints with, in slot order, read from the colours and filament types in your file. Only slots something prints with are listed, so the numbers can have gaps (a project using filaments 2 and 4 lists slots 2 and 4).
Order with
use_suggested_materials: trueon the order line to print with exactly these, or sendmaterialsas[{ slot, material }]for the same slots to choose your own.Null until
statusisready, on failed quotes, and on quotes created before suggestions existed. - approvalobject
The file in your account approval. Approval only matters until your account is approved; afterwards new quotes stay
not_submittedand are not reviewed one by one: an order goes to production once its quote isready. - created_attimestamp
Point in time, ISO 8601 in UTC.
- finished_attimestamp or null
When slicing finished, successfully or not. Null while
processing.
{
"id": "qte_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
"object": "quote",
"name": "Phone stand v2",
"file": {
"name": "phone-stand-v2.3mf",
"size_bytes": 2758723,
"download_url": "https://files.example.com/public-api/quotes/7f3a/input/phone-stand-v2.3mf?signature=abc",
"production_version": {
"name": "phone-stand-v2.3mf",
"format": "3mf",
"size_bytes": 2913004,
"download_url": "https://files.example.com/public-api/quotes/7f3a/production/phone-stand-v2.3mf?signature=def",
"prepared_at": "2026-10-20T09:12:09Z"
}
},
"status": "ready",
"suggested_materials": [
{
"slot": 1,
"file_color": "#C12E1F",
"file_filament_type": "PLA",
"material": {
"id": "mat_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
"object": "material",
"name": "PLA Red",
"custom": false
},
"match": "exact"
},
{
"slot": 3,
"file_color": "#0B2A88",
"file_filament_type": null,
"material": {
"id": "mat_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
"object": "material",
"name": "PLA Blue",
"custom": false
},
"match": "close"
}
],
"price": {
"amount": 1245,
"currency": "usd"
},
"failure_reason": null,
"approval": {
"status": "not_submitted",
"reason": null
},
"created_at": "2026-10-20T09:12:00Z",
"finished_at": "2026-10-20T09:13:41Z"
}List quotes
GET/
- Credentials
- An API key with the
quotes:readscope (full access includes every scope). A signed-in dashboard session works too. - For
- Integrators
- Operation id
list_quotes
Lists your quotes, newest first, with their price and approval status. Use the filters to find quotes to submit for approval (status=ready&approval_status=not_submitted). Integrators only; designers are refused with actor_not_allowed.
Query parameters
- statusarray of QuoteStatus
Only quotes in these states. Repeat for several.
Possible valuesprocessingreadyfailed - approval_statusarray of QuoteApprovalStatus
Only quotes in these approval states, for example
approval_status=not_submitted&status=readyfor the quotes you can still submit for approval.Possible valuesnot_submittedin_reviewapprovedrejected - created_aftertimestamp
Only quotes created at or after this time (ISO 8601).
- created_beforetimestamp
Only quotes created before this time (ISO 8601).
- limitinteger
How many results per page, from 1 to 100.
- cursorstring
Where to continue from: the
next_cursorof the previous page. Omit for the first page.
Returns200 OK
A page of quotes.
Responses
- 200
A page of quotes.
- 400
The request is invalid.
details.errorslists each problem (validation_failed), or anexpand[]path is unknown (invalid_expand). - 401
Credentials are missing (
missing_credentials), the API key is unknown or inactive (invalid_api_key), the session expired (invalid_session), or both a key and a session were sent (ambiguous_credentials). - 403
The credentials are valid but not allowed to do this: a scope is missing (
missing_scope), the endpoint is for another kind of account (actor_not_allowed) or another kind of credential (credential_not_allowed), the account may no longer use the API (account_blacklisted), or the account must change something first, in which casedetails.fix_urllinks to the dashboard page that fixes it. - 429
Too many requests (
rate_limited): the limit is 500 per minute per API key (or signed-in user). Wait for the number of seconds in theRetry-Afterheader, then retry;detailshaslimit,window_seconds,reset_atandretry_after_seconds.
Errors use the error object.
curl "https://public-api.dapi.digital/v2/quotes" \
-H "x-api-key: $DAPI_API_KEY"{
"object": "list",
"data": [
{
"id": "qte_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
"object": "quote",
"name": "Phone stand v2",
"file": {
"name": "phone-stand-v2.3mf",
"size_bytes": 2758723,
"download_url": "https://files.example.com/public-api/quotes/7f3a/input/phone-stand-v2.3mf?signature=abc",
"production_version": {
"name": "phone-stand-v2.3mf",
"format": "3mf",
"size_bytes": 2913004,
"download_url": "https://files.example.com/public-api/quotes/7f3a/production/phone-stand-v2.3mf?signature=def",
"prepared_at": "2026-10-20T09:12:09Z"
}
},
"status": "ready",
"suggested_materials": [
{
"slot": 1,
"file_color": "#C12E1F",
"file_filament_type": "PLA",
"material": {
"id": "mat_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
"object": "material",
"name": "PLA Red",
"custom": false
},
"match": "exact"
},
{
"slot": 3,
"file_color": "#0B2A88",
"file_filament_type": null,
"material": {
"id": "mat_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
"object": "material",
"name": "PLA Blue",
"custom": false
},
"match": "close"
}
],
"price": {
"amount": 1245,
"currency": "usd"
},
"failure_reason": null,
"approval": {
"status": "not_submitted",
"reason": null
},
"created_at": "2026-10-20T09:12:00Z",
"finished_at": "2026-10-20T09:13:41Z"
}
],
"has_more": false,
"next_cursor": null
}Quote a model file
POST/
- Credentials
- An API key with the
quotes:writescope (full access includes every scope). A signed-in dashboard session works too. - For
- Integrators
- Operation id
create_quote
Starts pricing one model file and returns the quote with status: processing. Poll get_quote until it is ready (with price) or failed.
While it is processing, 3DAPI first checks the file against its production printers and, when needed, prepares a production version with the right printer, process and filament settings (file.production_version). The price is for that version, since it is the file that gets printed; your upload stays downloadable as it is.
Upload the file first: POST /v2/uploads with purpose quote_file, PUT the bytes, then send the upload id here.
Limits before your account is approved: up to 25 quotes per round, and none while an approval request is in review. After a review that rejected files you get a fresh round of 25. Once approved, quotes are unlimited. A quote counts from the moment it is created, while it is processing and once it is ready; a quote that ends failed is given back to your allowance. get_integrator_onboarding shows how many you have used.
Integrators only; designers are refused with actor_not_allowed.
Headers
- Idempotency-Keystring
Any unique string, for example a UUID. Sending the same request again with the same key within 24 hours returns the first response without doing anything twice. Reusing a key with a different body is refused with
idempotency_key_reused. A refused request (4xx) frees the key so you can correct and resend it; a server error (5xx) is kept and returned again, because the write may already have happened: check the resource before retrying with a new key.
Request body
- fileobjectRequired
The model to quote, as
{ "upload": "upl_..." }fromPOST /v2/uploadswith purposequote_file. - namestring
Display name for the quote. Defaults to the uploaded file name.
Returns201 Created
The quote, being processed. Returns the quote object.
Responses
- 201
The quote, being processed.
- 400
The request is invalid (
validation_failed). - 401
Credentials are missing (
missing_credentials), the API key is unknown or inactive (invalid_api_key), the session expired (invalid_session), or both a key and a session were sent (ambiguous_credentials). - 403
The credentials are valid but not allowed to do this: a scope is missing (
missing_scope), the endpoint is for another kind of account (actor_not_allowed) or another kind of credential (credential_not_allowed), the account may no longer use the API (account_blacklisted), or the account must change something first, in which casedetails.fix_urllinks to the dashboard page that fixes it. - 409
Your account cannot quote right now: you used the 25 uploads of this round, so request approval next (
upload_limit_reached), or an approval request is in review and uploads resume once it is reviewed (approval_in_review). - 422
The upload is unknown, expired or of the wrong purpose (
unknown_upload,upload_expired,upload_purpose_mismatch), its file was never sent toupload_url(upload_missing), or the upload id was already used by another quote (upload_already_used; every upload id works once). - 429
The daily quote limit for accounts not yet approved is reached (
daily_quote_limit_reached). It resets at midnight UTC. Too many requests (rate_limited): the limit is 500 per minute per API key (or signed-in user), plus 60 per minute per API key (or signed-in user) for quote, upload, order and payment operations. Wait for the number of seconds in theRetry-Afterheader, then retry;detailshaslimit,window_seconds,reset_atandretry_after_seconds.
Errors use the error object.
curl -X POST "https://public-api.dapi.digital/v2/quotes" \
-H "x-api-key: $DAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"file": {
"upload": "upl_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu"
},
"name": "Phone stand v2"
}'{
"id": "qte_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
"object": "quote",
"name": "Phone stand v2",
"file": {
"name": "phone-stand-v2.3mf",
"size_bytes": 2758723,
"download_url": "https://files.example.com/public-api/quotes/7f3a/input/phone-stand-v2.3mf?signature=abc",
"production_version": null
},
"status": "processing",
"suggested_materials": null,
"price": null,
"failure_reason": null,
"approval": {
"status": "not_submitted",
"reason": null
},
"created_at": "2026-10-20T09:12:00Z",
"finished_at": null
}Get a quote
GET/
- Credentials
- An API key with the
quotes:readscope (full access includes every scope). A signed-in dashboard session works too. - For
- Integrators
- Operation id
get_quote
Returns one of your quotes. Poll it after create_quote until status is ready or failed; every few seconds is enough. Integrators only; designers are refused with actor_not_allowed.
Path parameters
- idstringRequired
Unique identifier of the quote, prefixed with
qte_. Treat it as an opaque string: store it and compare it, never parse it.
Returns200 OK
The quote. Returns the quote object.
Responses
- 200
The quote.
- 401
Credentials are missing (
missing_credentials), the API key is unknown or inactive (invalid_api_key), the session expired (invalid_session), or both a key and a session were sent (ambiguous_credentials). - 403
The credentials are valid but not allowed to do this: a scope is missing (
missing_scope), the endpoint is for another kind of account (actor_not_allowed) or another kind of credential (credential_not_allowed), the account may no longer use the API (account_blacklisted), or the account must change something first, in which casedetails.fix_urllinks to the dashboard page that fixes it. - 404
You have no quote with this id (
quote_not_found). - 429
Too many requests (
rate_limited): the limit is 500 per minute per API key (or signed-in user). Wait for the number of seconds in theRetry-Afterheader, then retry;detailshaslimit,window_seconds,reset_atandretry_after_seconds.
Errors use the error object.
curl "https://public-api.dapi.digital/v2/quotes/qte_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu" \
-H "x-api-key: $DAPI_API_KEY"{
"id": "qte_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
"object": "quote",
"name": "Phone stand v2",
"file": {
"name": "phone-stand-v2.3mf",
"size_bytes": 2758723,
"download_url": "https://files.example.com/public-api/quotes/7f3a/input/phone-stand-v2.3mf?signature=abc",
"production_version": {
"name": "phone-stand-v2.3mf",
"format": "3mf",
"size_bytes": 2913004,
"download_url": "https://files.example.com/public-api/quotes/7f3a/production/phone-stand-v2.3mf?signature=def",
"prepared_at": "2026-10-20T09:12:09Z"
}
},
"status": "ready",
"suggested_materials": [
{
"slot": 1,
"file_color": "#C12E1F",
"file_filament_type": "PLA",
"material": {
"id": "mat_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
"object": "material",
"name": "PLA Red",
"custom": false
},
"match": "exact"
},
{
"slot": 3,
"file_color": "#0B2A88",
"file_filament_type": null,
"material": {
"id": "mat_bfP0GSqKoZFrD72H5Os0rc7HV9XP6eQJu",
"object": "material",
"name": "PLA Blue",
"custom": false
},
"match": "close"
}
],
"price": {
"amount": 1245,
"currency": "usd"
},
"failure_reason": null,
"approval": {
"status": "not_submitted",
"reason": null
},
"created_at": "2026-10-20T09:12:00Z",
"finished_at": "2026-10-20T09:13:41Z"
}