Order with a custom file

View as Markdown

Prints your own .3mf or .stl on an order line instead of the variant's design, for example a keychain with a different name for every customer. Custom files are turned on per account: ask contact@dapi.digital. The variant must be a single design, and its production price is what the line costs, so the file should weigh about the same as the design it replaces. Files are not reviewed or re-sliced: they go straight to production as sent.

What you need

  • variantstringRequired

    The variant to print (var_...): yours, active, approved and a single design.

  • file_namestringRequired

    Name of the file to print, ending in .3mf or .stl, for example keychain-anna.3mf.

  • content_typestringRequired

    MIME type of the file: model/3mf or model/stl.

  • size_bytesintegerRequired

    Size of the file in bytes, up to 1 GiB.

  • customerobjectRequired

    The recipient: name, email and optionally phone.

  • shipping_addressobjectRequired

    Where to ship: line1, city, country_code (ISO alpha-2) and optionally line2, state, postal_code.

  • idempotency_keystringRequired

    A unique string for this attempt, for example a UUID. Send the same value when you retry, so the write happens once.

Step 1: Start a file upload

POST/v2/uploads

Reserve an upload for the file to print, with purpose order_file. Then send the file bytes to upload_url with the returned method and headers. That transfer goes straight to storage, not to this API, so it is not a step here; do it before the next step.

Request body
{
  "purpose": "order_file",
  "file_name": "$inputs.file_name",
  "content_type": "$inputs.content_type",
  "size_bytes": "$inputs.size_bytes"
}

Succeeds when:

  • $statusCode == 201

Keeps for the next steps:

  • upload_id: $response.body#/id

Step 2: Create an order

POST/v2/orders

Create and pay the order, the line naming the upload in file. Its items[].custom_file shows the file. custom_files_not_enabled (403) means custom files are not on for your account. variant_not_orderable (422) also covers a variant made of several designs; an upload that is unknown, expired, already used or not a real .3mf or .stl is refused with its own 422 code. payment_failed (402) means no order was created.

Parameters
{
  "header Idempotency-Key": "$inputs.idempotency_key"
}
Request body
{
  "items": [
    {
      "variant": "$inputs.variant",
      "quantity": 1,
      "file": {
        "upload": "$steps.upload_file.outputs.upload_id"
      }
    }
  ],
  "customer": "$inputs.customer",
  "shipping_address": "$inputs.shipping_address"
}

Succeeds when:

  • $statusCode == 201

Otherwise:

  • retry_server_error: retry after 5 seconds, at most 3 times, when $statusCode >= 500.
  • custom_files_not_enabled: stop the workflow when $statusCode == 403.
  • payment_failed: stop the workflow when $statusCode == 402.
  • not_orderable: stop the workflow when $statusCode == 422.

Keeps for the next steps:

  • order_id: $response.body#/id
  • number: $response.body#/number
  • total: $response.body#/charges/total

As a workflow file

The workflow returns:

  • order_id: $steps.create_order.outputs.order_id
  • number: $steps.create_order.outputs.number
  • total: $steps.create_order.outputs.total

Values starting with $ are filled in as you go: $inputs.x is something you provide, $steps.s.outputs.o is a value an earlier step returned, and $response.body#/path a field of this response.

This recipe is the workflow order_with_custom_file of arazzo.json, an Arazzo 1.0 document that tools and AI agents can follow step by step.