This walk-through takes you from a company account to a test order that reports its progress to your webhook. Everything happens in the test environment; the last step is the switch to live.
1. Register your company
Sign up at /developers/register with your company's name, legal identifier or VAT number, country and a contact. Partners are companies, so the form has no private-individual option. A Romanian company is checked against ANAF; an EU company against the VAT register when it answers.
2. Accept the agreements
In your dashboard under Integrations → Agreement, read and accept the integration agreement and the data processing agreement together. Acceptance is recorded — who, when, from which address, which version — and the PDF is emailed to you. LayerCrew countersigns in AdminCrew and the countersigned PDF goes to both sides; agreement.countersigned appears in your event feed.
3. Create a test key
Under Integrations → Keys, create a test key. It looks like lc_test_<16 characters>_<64 hex characters> and is shown once: store it in your secret manager. Check it:
curl "https://engine.layercrew.com/v1/ping" \
-H "Authorization: Bearer $LAYERCREW_API_KEY"4. Upload a file
Uploading is two calls and one PUT. First declare the file with its size in bytes and the lowercase hex SHA-256 of the exact bytes you will send:
curl -X POST "https://engine.layercrew.com/v1/files" \
-H "Authorization: Bearer $LAYERCREW_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filename": "bracket-v3.stl",
"size_bytes": 1048576,
"sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
}'PUT the raw bytes to upload.url before expires_at, sending exactly the headers in upload.headers. Both headers are mandatory — Content-Type and x-goog-content-length-range — because the signature covers them; a PUT missing either is refused by the storage service.
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/octet-stream" \
-H "x-goog-content-length-range: 0,1048576" \
--data-binary @bracket-v3.stl5. Complete the upload
Tell us the bytes are there. We check the object's size and hash against what you declared, read the model, strip any embedded slicer scripts from a 3MF and store the canonical copy:
curl -X POST "https://engine.layercrew.com/v1/files/4f1b2c3d-5e6f-4a7b-8c9d-0e1f2a3b4c5d/complete" \
-H "Authorization: Bearer $LAYERCREW_API_KEY"status is ready, or rejected with a rejection_code you can act on — see Files. complete is idempotent: call it again and you get the same file back.
6. Ask for a price (optional)
curl -X POST "https://engine.layercrew.com/v1/quotes" \
-H "Authorization: Bearer $LAYERCREW_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "file_id": "4f1b2c3d-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "material": "PLA", "quantity": 2 }'The answer is 202 with the quote in pending. Pricing slices the file for real and takes seconds to a few minutes; poll GET /v1/quotes/{id} until status is priced, or listen for quote.priced. See Quotes.
7. Create an order
An order needs your own reference (unique in this environment), the items, your customer's delivery address and an Idempotency-Key header:
curl -X POST "https://engine.layercrew.com/v1/orders" \
-H "Authorization: Bearer $LAYERCREW_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"reference": "SHOP-10231",
"items": [
{
"file_id": "4f1b2c3d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"quantity": 2,
"material": "PLA",
"colour": "black",
"nozzle": "0.4"
}
],
"delivery": {
"name": "Claire Martin",
"phone": "+33 6 12 34 56 78",
"email": "claire@example.com",
"line1": "12 rue de la Paix",
"city": "Lyon",
"postal_code": "69001",
"country_code": "FR"
},
"white_label": {
"sender_name": "Studio NS",
"card_text": "Merci Claire — Studio NS",
"language": "fr"
},
"metadata": {
"shop_order_id": "10231"
}
}'A retry with the same key and the same body returns the first answer with Idempotent-Replayed: true; the same key with a different body answers 409 IDEMPOTENCY_KEY_REUSED. A second order with the same reference answers 409 REFERENCE_TAKEN and names the existing one. See Orders and Idempotency.
8. Follow the order
Every change is an event with a per-partner seq. Poll the account feed from the last seq you processed; meta.next_after and meta.has_more drive the loop:
curl "https://engine.layercrew.com/v1/events?after=0&limit=50" \
-H "Authorization: Bearer $LAYERCREW_API_KEY"A live order moves as production happens. In the test environment you move it yourself, and each move emits the same event a live order would:
curl -X POST "https://engine.layercrew.com/v1/test/orders/7a3e9c10-2b4d-4f61-9e8a-5c6d7e8f9a0b/advance" \
-H "Authorization: Bearer $LAYERCREW_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "to": "accepted" }'9. Receive webhooks
curl -X POST "https://engine.layercrew.com/v1/webhook-endpoints" \
-H "Authorization: Bearer $LAYERCREW_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://shop.example.com/webhooks/layercrew", "description": "Production events" }'Store the secret. Send yourself a signed test event and verify it with the snippet for your language on the Webhooks page:
curl -X POST "https://engine.layercrew.com/v1/webhook-endpoints/c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f/ping" \
-H "Authorization: Bearer $LAYERCREW_API_KEY"10. Go live
- Wait for
agreement.countersigned, or checkGET /v1/account: both agreements showcountersigned. - Create a live key under Integrations → Keys (the account owner does this) and store it next to the test one.
- Register your production webhook endpoint with the live key — endpoints, files, quotes and orders are per environment.
- Switch the key in your configuration. Nothing else changes: same routes, same bodies, same events.