API

Coming soon

Send a file and an address, and Craftshop prints it, checks it and ships it, notifying you by webhook at every stage.

Preview

Coming soon

Create an order

cURLbash
curl https://api.craftshoplabs.com/v1/orders \
  -H "Authorization: Bearer $CRAFTSHOP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "MOD-0020",
    "quantity": 1,
    "material": "PETG Negro",
    "ship_to": {
      "name": "Ana Gómez",
      "address": "Av. Corrientes 1234, Piso 3",
      "city": "Ciudad Autónoma de Buenos Aires",
      "postal_code": "C1043AAZ",
      "country": "AR"
    }
  }'
Node.jsjavascript
const response = await fetch('https://api.craftshoplabs.com/v1/orders', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CRAFTSHOP_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'MOD-0020',
    quantity: 1,
    material: 'PETG Negro',
    ship_to: {
      name: 'Ana Gómez',
      address: 'Av. Corrientes 1234, Piso 3',
      city: 'Ciudad Autónoma de Buenos Aires',
      postal_code: 'C1043AAZ',
      country: 'AR',
    },
  }),
})

const order = await response.json()
Pythonpython
import os

import requests

api_key = os.environ["CRAFTSHOP_API_KEY"]

response = requests.post(
    "https://api.craftshoplabs.com/v1/orders",
    headers={"Authorization": f"Bearer {api_key}"},
    json={
        "model": "MOD-0020",
        "quantity": 1,
        "material": "PETG Negro",
        "ship_to": {
            "name": "Ana Gómez",
            "address": "Av. Corrientes 1234, Piso 3",
            "city": "Ciudad Autónoma de Buenos Aires",
            "postal_code": "C1043AAZ",
            "country": "AR",
        },
    },
)

order = response.json()
Rustrust
let api_key = std::env::var("CRAFTSHOP_API_KEY")?;

let order: serde_json::Value = reqwest::Client::new()
    .post("https://api.craftshoplabs.com/v1/orders")
    .bearer_auth(api_key)
    .json(&serde_json::json!({
        "model": "MOD-0020",
        "quantity": 1,
        "material": "PETG Negro",
        "ship_to": {
            "name": "Ana Gómez",
            "address": "Av. Corrientes 1234, Piso 3",
            "city": "Ciudad Autónoma de Buenos Aires",
            "postal_code": "C1043AAZ",
            "country": "AR"
        }
    }))
    .send()
    .await?
    .json()
    .await?;
TypeScript SDKtypescript
const craftshop = new Craftshop({ apiKey: process.env.CRAFTSHOP_API_KEY })

const order = await craftshop.orders.create({
  model: 'MOD-0020',
  quantity: 1,
  material: 'PETG Negro',
  shipTo: {
    name: 'Ana Gómez',
    address: 'Av. Corrientes 1234, Piso 3',
    city: 'Ciudad Autónoma de Buenos Aires',
    postalCode: 'C1043AAZ',
    country: 'AR',
  },
})
Stage webhookjson
{
  "type": "job.status_changed",
  "job": "JOB-0142",
  "order": "ord_7Hq2mX",
  "status": "qc_passed",
  "occurred_at": "2026-09-30T11:08:00-03:00"
}
This is how an order will be created and how each stage change will arrive. Preview of the planned product: it isn't available yet and the details may change.

What it does

  • Endpoints for models and orders

    Upload models, create orders and check their status with per-organization API keys.

  • A webhook per stage

    Queued, printing, QC and shipped: every change reaches you as an event, just as the app shows it.

  • A sandbox to try it

    Try the whole flow without manufacturing anything. Docs, SDKs and a CLI come later, generated from the same contract.

Where it fits in the flow

It is another way in: instead of a sale in your store, an order over the API that follows the same flow.

  1. Store (part of this product)
  2. Model
  3. Golden sample
  4. Jobs (part of this product)
  5. Quality check (part of this product)
  6. Shipping (part of this product)

Today and what's next

What works today

  • The app already runs on the service layer the API will expose.
  • Orders, jobs and shipments with an event recorded on every change.

What's coming

  • Per-organization API keys and endpoints for models and orders.
  • Stage webhooks and a sandbox.
  • Docs, SDKs and a CLI.

Start with what works today.

You create your brand, choose who prints and connect Shopify. What's coming joins the same account, without changing how you work.

Waitlist

Bring your brand to Craftshop

We're opening one brand at a time. Leave your email and we'll write when there's room for yours.

Once your brand is in

  • Every sale is printed piece by piece

    An order from your store reaches the workshop as one job per piece, and the tracking goes back to your store so the buyer sees it where they bought.

  • Nothing ships without a photo check

    You approve a golden sample per model and workshop. Before dispatch, every piece passes a photo check against that sample.

  • You start with Shopify

    Connect your Shopify store and upload each model once. Tiendanube and Mercado Libre join next, each with its own integration.