Skip to content

Instant price: upload your file and see it before you register.

HazTuPieza

API

Send a file and a configuration and we'll return the price straight away: 3D printing and acrylic (PMMA) laser cutting. It's the same engine that calculates prices on the website, so any agreed rates are applied automatically.

Getting started

You need an account and a key. Create the key from Account → API keys. It is shown only once: we don't store it in plain text, so if you lose it you'll need to revoke it and create another one.

Everything uses HTTPS and returns JSON. Requests with a body expect JSON with Content-Type: application/json; requests with a file use multipart.

To check that the key works, any endpoint will do:

curl https://haztupieza.es/api/v1/orders \
  -H "Authorization: Bearer htp_TU_CLAVE"

Get a quote

Getting a quote is free and creates nothing: no saved quote, no cart and no order. You can call it repeatedly while adjusting dimensions.

With a file

POST/api/v1/quotes/file

The quick way: upload the part and we measure it for you. It works for 3D printing and laser cutting; the process is inferred from the file extension.

3D printing — an STL, a 3MF or a STEP:

curl https://haztupieza.es/api/v1/quotes/file \
  -H "Authorization: Bearer htp_TU_CLAVE" \
  -F "file=@soporte.stl" \
  -F 'config={"materialId":"pla","colorId":"negro","qualityId":"standard","infillId":"i25","quantity":4,"supports":true,"leadTimeId":"standard"}'

Laser cutting — an SVG or a DXF. The dimensions come from the drawing itself:

curl https://haztupieza.es/api/v1/quotes/file \
  -H "Authorization: Bearer htp_TU_CLAVE" \
  -F "file=@tapa.svg" \
  -F 'config={"sheetId":"pmma-colada-incoloro-3","quantity":10,"leadTimeId":"standard"}'

The response includes what we measured, as well as the price:

200 OK
{
  "ok": true,
  "errors": [],
  "total": 24.18,
  "breakdown": {
    "unitPrice": 6.045,
    "lines": [
      { "id": "material", "label": "Material", "amount": 4.12 },
      { "id": "machine", "label": "Máquina", "amount": 11.4 },
      { "id": "finishing", "label": "Acabados", "amount": 4.9 }
    ],
    "taxRate": 0.21,
    "leadTimeDays": 3
  },
  "file": {
    "name": "soporte.stl",
    "mesh": {
      "volumeCm3": 18.42,
      "surfaceCm2": 96.3,
      "boundingBoxMm": { "x": 62.4, "y": 41, "z": 18 },
      "triangles": 24680,
      "watertight": true,
      "hash": "9f2c1a7b"
    }
  }
}

We don't keep the file. It is measured in memory and then discarded. If we can't open the format —SolidWorks, Illustrator— the response is 200 with «manualReview» set to true and the reason: a person will quote it.

With the geometry already measured

POST/api/v1/quotes

If you already have the part volume and bounding box —because you measure it yourself or saved them from an earlier quote— you can skip uploading the file.

curl https://haztupieza.es/api/v1/quotes \
  -H "Authorization: Bearer htp_TU_CLAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "process": "FDM_3D",
    "label": "soporte.stl",
    "config": {
      "materialId": "pla",
      "colorId": "negro",
      "qualityId": "standard",
      "infillId": "i25",
      "quantity": 4,
      "supports": true,
      "leadTimeId": "standard"
    },
    "mesh": {
      "volumeCm3": 18.42,
      "surfaceCm2": 96.3,
      "boundingBoxMm": {
        "x": 62.4,
        "y": 41,
        "z": 18
      },
      "triangles": 24680,
      "watertight": true,
      "hash": "9f2c1a7b"
    }
  }'

A 200 doesn't always mean yes. When the part can't be made —that sheet is no longer available, the size doesn't fit the machine— the response is still 200 with «ok» set to false and the reason in «errors». It's a response, not a failure: retrying would give exactly the same result. Always check «ok».

Laser cutting, all fields

Without a file, you can request any shape from the catalogue. This example includes everything the endpoint accepts, with the default values shown; almost nothing is required.

curl https://haztupieza.es/api/v1/quotes \
  -H "Authorization: Bearer htp_TU_CLAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "process": "LASER_ACRYLIC",
    "label": "frontal",
    "config": {
      "sheetId": "pmma-colada-incoloro-3",
      "shape": "ROUNDED_RECT",
      "shapeId": "rounded-rect",
      "shapeParams": {
        "w": 300,
        "h": 200,
        "radius": 12
      },
      "widthMm": 300,
      "heightMm": 200,
      "cornerRadiusMm": 12,
      "innerDiameterMm": 0,
      "quantity": 10,
      "cutouts": [
        {
          "id": "ventana",
          "shapeId": "circle",
          "params": {
            "d": 22
          },
          "xMm": 60,
          "yMm": 100,
          "rotationDeg": 0,
          "conservarPieza": true
        },
        {
          "id": "ranura",
          "shapeId": "stadium",
          "params": {
            "w": 40,
            "h": 8
          },
          "xMm": 240,
          "yMm": 100,
          "rotationDeg": 90
        },
        {
          "id": "rotulo",
          "shapeId": "texto",
          "params": {},
          "texto": {
            "texto": "SALIDA",
            "tipografiaId": "stardos-stencil",
            "alturaMm": 25
          },
          "xMm": 150,
          "yMm": 100,
          "rotationDeg": 0
        }
      ],
      "holes": {
        "pattern": "CORNERS",
        "diameterMm": 4,
        "edgeDistanceMm": 10,
        "count": 4,
        "edgeCounts": [
          2,
          2,
          2,
          2
        ],
        "rows": 0,
        "columns": 0,
        "centerDistanceMm": 0,
        "points": []
      },
      "engraveAreaCm2": 0,
      "leadTimeId": "express",
      "vectorPendingReview": false,
      "notes": "Cantos pulidos por la cara vista."
    }
  }'

Only these are required: sheetId, shape, widthMm, heightMm, quantity, leadTimeId

shapeId: "texto" — cuts the text as the outline of the part, using the font and height you specify.

curl https://haztupieza.es/api/v1/quotes \
  -H "Authorization: Bearer htp_TU_CLAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "process": "LASER_ACRYLIC",
    "config": {
      "sheetId": "pmma-colada-incoloro-3",
      "shape": "CUSTOM",
      "shapeId": "texto",
      "texto": {
        "texto": "ABIERTO",
        "tipografiaId": "anton",
        "alturaMm": 80
      },
      "widthMm": 400,
      "heightMm": 80,
      "quantity": 2,
      "leadTimeId": "standard"
    }
  }'

3D printing, all fields

The same for FDM: the long example, including the optional fields.

curl https://haztupieza.es/api/v1/quotes/file \
  -H "Authorization: Bearer htp_TU_CLAVE" \
  -F "file=@pieza.3mf" \
  -F 'config={"materialId":"pla","colorId":"negro","qualityId":"standard","infillId":"i25","quantity":4,"supports":true,"leadTimeId":"standard","finishIds":["sanding"],"extraColorIds":["rojo"],"plateId":"auto","nozzleId":"auto","pauses":[{"layer":40,"action":"Colocar 4 tuercas M3 en los alojamientos","inserts":[{"optionId":"tuerca-m3","quantity":4}]}],"notes":"La cara buena es la de arriba."}'

Options

The identifiers accepted by «materialId», «sheetId» and the rest. This list comes from the same catalogue the workshop uses and changes when the catalogue changes: don't copy it, request it.

Everything below, in one call and always up to date:

GET/api/v1/catalog

curl https://haztupieza.es/api/v1/catalog \
  -H "Authorization: Bearer htp_TU_CLAVE"

And this is how it looks today:

Materials (3D printing)

IdentifierNameDetails
plaPLAPLA · 15 colores
pla-alta-resistenciaPLA alta resistenciaPLA · 9 colores
pla-matePLA MatePLA · 3 colores
pla-recicladoPLA RecicladoPLA · 3 colores
pla-sedaPLA SilkPLA · 7 colores
pla-maderaPLA MaderaPLA · 3 colores
pla-marmolPLA MarmolPLA · 2 colores
pla-glitterPLA GlitterPLA · 4 colores
pla-fluorescentePLA Fluorescente (glow in the dark)PLA · 2 colores
pla-metalizadoPLA MetalizadoPLA · 4 colores
petgPETGPETG · 7 colores
absABS-EABS · 5 colores
asaASAASA · 4 colores
tpu-95aTPU 95A FlexTPU · 5 colores
nylon-paNylon PAPA · 2 colores
hipsHIPSHIPS · 2 colores

Each material includes its colours in «colors». The colour ID goes in «colorId».

Qualities

IdentifierNameDetails
draftBorrador 0,28 mm0.28 mm
standardEstándar 0,20 mm0.2 mm
fineFina 0,16 mm0.16 mm
ultraUltrafina 0,12 mm0.12 mm

Infill options

IdentifierNameDetails
i1515 % ligero15 %
i2525 % estándar25 %
i4040 % resistente40 %
i6060 % robusto60 %
i100100 % macizo100 %

Acrylic (PMMA) sheets (laser cutting)

IdentifierNameDetails
pmma-colada-incoloro-3Metacrilato transparente 3 mm3 mm · 1000×600 mm
pmma-colada-incoloro-5Metacrilato transparente 5 mm5 mm · 1000×600 mm
pmma-colada-incoloro-6Metacrilato transparente 6 mm6 mm · 1000×600 mm
pmma-colada-incoloro-8Metacrilato transparente 8 mm8 mm · 1000×600 mm
pmma-colada-incoloro-10Metacrilato transparente 10 mm10 mm · 1000×600 mm
pmma-extrusion-incoloro-3Metacrilato extrusión transparente 3 mm3 mm · 1000×600 mm
pmma-extrusion-incoloro-5Metacrilato extrusión transparente 5 mm5 mm · 1000×600 mm
pmma-blanco-3Metacrilato opal 3 mm3 mm · 1000×600 mm
pmma-negro-3Metacrilato negro 3 mm3 mm · 1000×600 mm
pmma-tintado-3-rojoMetacrilato tintado rojo 3 mm3 mm · 1000×600 mm
pmma-tintado-3-azulMetacrilato tintado azul 3 mm3 mm · 1000×600 mm
pmma-tintado-3-verdeMetacrilato tintado verde 3 mm3 mm · 1000×600 mm
pmma-tintado-3-ambarMetacrilato tintado ámbar 3 mm3 mm · 1000×600 mm
pmma-tintado-3-fumeMetacrilato tintado fumé 3 mm3 mm · 1000×600 mm
dm-3DM 3 mm3 mm · 800×400 mm
pmma-fluor-3-naranjaMetacrilato fluorescente naranja 3 mm3 mm · 1000×600 mm
pmma-fluor-3-rojoMetacrilato fluorescente rojo 3 mm3 mm · 1000×600 mm
pmma-fluor-3-verdeMetacrilato fluorescente verde 3 mm3 mm · 1000×600 mm

Catalogue shapes

IdentifierNameshapeParams
rectRectángulow, h
rect-bevelRectángulo achaflanadow, h, bevel
rect-cornerRectángulo con esquina cortadaw, h, cutW, cutH
rect-slantRectángulo con lado inclinadow, hLeft, hRight
separadorSeparador de estanteríaw, h, frente
triangleTriángulow, h
triangle-rightTriángulo rectángulow, h
triangle-right-mirrorTriángulo rectángulo invertidow, h
trapezoidTrapeciowTop, wBottom, h
parallelogramParalelogramow, h, offset
hexagonHexágonow, h
octagonOctágonow, h, bevel
polygonPolígono regularsides, d
rounded-rectRectángulo redondeadow, h, radius
circleCírculod
ringCoronad, inner
ovalÓvalow, h
stadiumÓvalo planow, h
semicircleSemicírculod
quarter-circleCuarto de círculor
archArcow, h
barrelTonelw, h, bulge
starEstrellapoints, d, inner
heartCorazónw, h
dropGotaw, h
arrowFlechaw, h, stem, head
kiteCometaw, h, cross
gemGemaw, h, crown, top

«shapeId» selects the shape and «shapeParams» passes its dimensions, which are different for each one. Neither is needed with a file or a custom rectangle.

Hole patterns

IdentifierNameDetails
NONESin agujeros—
CORNERSEn las esquinasdiameterMm, edgeDistanceMm
PERIMETERRepartidos por el bordediameterMm, edgeDistanceMm, count o edgeCounts
RADIALEn círculodiameterMm, count, centerDistanceMm
GRIDEn cuadrículadiameterMm, rows, columns, centerDistanceMm
POINTSEn coordenadas concretasdiameterMm, points[{ xMm, yMm }]
CUSTOMLos que traiga el archivo—

Lead times

IdentifierNameDetails
standardEstándar3 días laborables
expressExprés 48 h2 días laborables
urgentUrgente 24 h1 días laborables

File formats

Formats we accept, and what we do with each one:

IdentifierProcesoDetails
.stl .obj .3mf .plyFDM_3DSe miden solas. Precio al momento.
.step .stp .iges .igs .brepFDM_3DSe teselan en el servidor. Precio al momento.
.sldprt .ipt .f3d .3dm .sat .x_tFDM_3DCAD propietario: lo cotiza una persona.
.svg .dxfLASER_ACRYLICSe miden solas. Precio al momento.
.aiLASER_ACRYLICLo cotiza una persona.

Orders

GET/api/v1/orders

The latest fifty, newest first, with their status and tracking.

GET/api/v1/orders/{code}

One specific order, with its lines and amounts.

200 OK
{
  "order": {
    "code": "HTP-3MQ8N-LY45L",
    "status": "IN_PRODUCTION",
    "total": 43.05,
    "trackingCarrier": "MRW",
    "trackingNumber": "0123456789",
    "items": [
      { "label": "tapa.svg", "quantity": 10, "process": "LASER_ACRYLIC",
        "unitPrice": 3.55, "total": 35.5 }
    ]
  }
}

Possible statuses are: AWAITING_PAYMENT, PAID, IN_PRODUCTION, QUALITY_CHECK, READY_FOR_PICKUP, SHIPPED, DELIVERED, CANCELLED, REFUNDED

Request limit

60 requests per minute and key. Every response tells you how many you have left, so you don't need to hit the limit to know where it is:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 42

If you go over, you get a 429 with «Retry-After» in seconds. It's not a punishment: quoting builds the geometry of the part and checks the stock, and a badly closed loop can leave everyone else without service.

When something goes wrong

Always a JSON with «code» —stable, so you can make decisions from it— and «error», which is the message to read.

  • 401 unauthorized — the key is missing, invalid or has been revoked.
  • 404 not_found — that order isn't yours. We return the same response if it doesn't exist; otherwise it could be used to find out which codes exist.
  • 422 invalid_request — the configuration is invalid. It includes «details» field by field.
  • 429 rate_limited — you've exceeded the limit.

For assistants and agents

If you're integrating this into an assistant: with the customer's key and a file, you can get a quote in a single call, with no previous steps and without uploading anything anywhere first.

There is a machine-readable description in two formats:

  • /openapi.json — the full contract, for generating a client or loading it as a tool.
  • /llms.txt — a short plain-text summary to put into context.

What isn't available yet

Place an order. You can get a quote, but you can't buy yet. We first need to agree how payment will work —invoice, credit— and that's a conversation, not an endpoint. If you're interested, write to us and we'll talk: it's one step away from being ready.

Missing something, or does something not work as described here? Tell us. The person who wrote it will reply.