본문으로 건너뛰기
신규 VERI*FACTU가 2027년에 시행됩니다. elpizzero는 이미 준비되어 있습니다. 자세히 보기 상담할까요?Partners: para agencias
API Export 읽기 전용 · api@elpizzero.com

API Export

elpizzero 계정의 데이터(주문, 메뉴, 배달 구역, 레스토랑 정보, 지표)를 CRM, BI, 회계, 디스플레이 등 자체 시스템으로 내보내기 위한 읽기 전용 REST API입니다. 변경 사항에 실시간으로 대응할 수 있도록 라이브 스트림(SSE)과 발신 webhook을 제공합니다.

범위. 이 API는 주문을 생성하거나 수정하지 않습니다. elpizzero 로 주문을 수집하는 기능은 공개되어 있지 않으며 여기에 문서화되어 있지 않습니다. 계정별로 사전 검토를 거쳐 활성화됩니다. 필요하시면 api@elpizzero.com으로 문의해 주세요.

인증

헤더를 통한 Bearer token. token 형식은 elp_live_<32hex> 또는 elp_test_<32hex>입니다.

Authorization: Bearer elp_live_3b8f0c2a1d4e5f6079a8b7c6d5e4f3a2

token은 패널 → 연동 → API 키에서 권한을 선택하여 생성하고 폐기합니다. token은 단 한 번만 전체가 표시됩니다.

권한

Scope활성화되는 기능
pedidos.leer/pedidos, /pedidos/{id}, /pedidos/{id}/historial, /resumen
carta.leer/carta
restaurante.leer/restaurante, /zonas
stream.escuchar/stream (SSE)
webhook.recibir/webhooks (등록/삭제/목록)

필요한 스코프가 없는 token → 403 alcance_insuficiente.

환경

elp_live_와 elp_test_는 동일한 실제 데이터를 읽습니다. 모의 데이터가 있는 샌드박스는 없습니다. 접두사는 token을 구분하기 위한 라벨일 뿐입니다.

Rate limit

token당 분당 60회 요청. 모든 응답에 다음 헤더가 포함됩니다: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. 초과 시 → 429 + Retry-After.

규칙

오류

일관된 본문 + 일관된 HTTP 코드:

{
  "ok": false,
  "error": "Esta llave no tiene el alcance necesario: pedidos.leer",
  "codigo": "alcance_insuficiente",
  "doc": "https://elpizzero.com/docs/api/export#auth"
}
HTTPcodigo
401llave_ausente · llave_invalida · llave_revocada · llave_expirada
403alcance_insuficiente · restaurante_inactivo
400parametro_invalido (valores_validos 포함)
404no_encontrado
405 / 429metodo_invalido · limite_alcanzado

주문 목록

GET /pedidos

레스토랑의 주문을 id 내림차순으로 반환하며, cursor 페이지네이션을 사용합니다.

QueryTipo설명
estadocsvpendienteconfirmadoen_preparacionlistoen_repartoentregadocancelado
tipoenumrepartorecogidamesa
desde / hastaISOcreado_en 기준 범위(desde ≤ x < hasta).
limiteint1–100, 기본값 25.
cursorstring이전 페이지의 paginacion.siguiente 값.
curl "https://elpizzero.com/api/export/pedidos?estado=entregado&desde=2026-05-01&limite=50" \
  -H "Authorization: Bearer elp_live_..."
{
  "datos": [ /* Objeto Pedido */ ],
  "paginacion": { "limite":50, "siguiente":"ni", "anterior":null, "total_aprox":494 }
}
전체 이력을 가져오려면 cursor = paginacion.siguiente로 null이 될 때까지 반복하세요.

주문 조회

GET /pedidos/{id}

주문 객체를 반환합니다. {id}는 접두사가 붙은 ID입니다(예: ped_ni). 본인의 주문이 아니면 404 no_encontrado.

주문 이력

GET /pedidos/{id}/historial
{
  "pedido_id": "ped_ni",
  "eventos": [
    { "momento":"2026-05-31T20:42:15Z", "accion":"order_created",
      "origen":"sistema", // sistema|panel|tpv|apk_recepcion|api
      "usuario":null, "detalle":{} }
  ]
}

메뉴

GET /carta

카테고리 → 상품 → 사이즈 → 옵션 그룹 → 옵션으로 이어지는 전체 트리. ?solo_disponibles=true를 사용하면 숨김/품절 항목이 제외됩니다.

{
  "restaurante_id":"rest_1", "restaurante_slug":"tu-restaurante",
  "moneda":"EUR", "idioma_origen":"es", "generado_en":"2026-06-01T18:41:27Z",
  "categorias": [{
    "id":"cat_v", "nombre":"Pizzas", "activa":true,
    "visible_dias":["lun","mar","mie","jue","vie","sab","dom"], "visible_horario":null,
    "productos": [{
      "id":"prod_3J", "nombre":"Margarita", "precio_cents":680,
      "disponible":true, "destacado":false, "alergenos":["gluten","lacteos"],
      "tamaños":[{ "id":"tam_11", "nombre":"mediana", "precio_cents":680, "predeterminado":true }],
      "grupos_opcion":[{ "id":"grp_73", "nombre":"Extras", "requerido":false,
        "min_seleccion":0, "max_seleccion":5,
        "opciones":[{ "id":"opt_8", "nombre":"Extra queso", "precio_cents":120 }] }]
    }]
  }]
}

배달 구역

GET /zonas

GeoJSON 폴리곤으로 된 배달 구역(좌표는 [lng, lat], 닫힌 링).

{ "datos": [{
  "id":"zon_8", "nombre":"Albatera", "slug":"albatera",
  "color":"#44c3e5", "tarifa_cents":250, "pedido_minimo_cents":2000,
  "minutos_estimados":40, "activa":true,
  "poligono":{ "tipo":"Polygon", "coordenadas":[[[-0.872,38.186], /* … */]] }
}] }

레스토랑

GET /restaurante

레스토랑 정보: 연락처, 위치, 요일별 영업시간, 브랜딩, 채널별 언어, 평판. 민감한 세무 정보는 포함되지 않습니다.

{
  "id":"rest_1", "slug":"tu-restaurante", "nombre":"Tu Restaurante",
  "moneda":"EUR", "zona_horaria":"Europe/Madrid",
  "acepta_pedidos":true, "pedido_minimo_cents":500,
  "horario":{ "viernes":[{"desde":"18:45","hasta":"23:30"}] /* … */ },
  "contacto":{ "email":"…", "telefono":"…", "web":"…" },
  "ubicacion":{ "direccion":"…", "ciudad":"…", "lat":38.14, "lng":-0.88 },
  "branding":{ "logo_url":"…", "color_primario":"…", "galeria":[] },
  "reputacion":{ "puntuacion":4.7, "votos":128 }
}

요약 / 지표

GET /resumen?periodo=30d

periodo ∈ hoyayer7d30dmes_actual. 레스토랑의 시간대 기준으로 계산되며 취소/거부된 주문은 제외됩니다.

{
  "periodo":"30d", "desde":"2026-05-03T00:00:00+02:00", "hasta":"2026-06-02T00:00:00+02:00",
  "zona_horaria":"Europe/Madrid",
  "kpis":{ "pedidos_total":442, "pedidos_cancelados":52, "clientes_distintos":413,
    "ventas_cents":893435, "ticket_medio_cents":2021, "moneda":"EUR" },
  "mix_tipo":{ "reparto":268, "recogida":171, "mesa":3 },
  "top_productos":[{ "producto_id":"prod_3K", "nombre":"Margarita", "unidades":150, "ventas_cents":113845 }]
}

라이브 스트림(SSE)

GET /stream

Server-Sent Events. 이벤트를 즉시 푸시합니다. 인증은 쿼리로 합니다(EventSource는 헤더를 지원하지 않음). 5분마다 Last-Event-ID를 통한 기본 재연결이 이루어지며, conexion.ping은 약 25초마다 전송됩니다.

const es = new EventSource("https://elpizzero.com/api/export/stream?llave=elp_live_...");
es.addEventListener("pedido.nuevo", e => {
  const ev = JSON.parse(e.data);   // ev.datos.pedido = Objeto Pedido
  console.log(ev.datos.pedido.numero);
});

선택적 필터 ?eventos=pedido.nuevo,pedido.aceptado. 발생하는 이벤트 유형:

pedido.nuevopedido.aceptadopedido.rechazadopedido.estado_cambiadopedido.item_modificadopedido.entregadopedido.cancelado

발신 webhook

pull에서 push로의 대안: 주문이 변경되면 지정한 URL로 POST를 보냅니다. 발신 전용입니다.

POST /webhooks
curl -X POST "https://elpizzero.com/api/export/webhooks" \
  -H "Authorization: Bearer elp_live_..." -H "Content-Type: application/json" \
  -d '{"url":"https://tu-sistema.com/hook","nombre":"Mi CRM","eventos":["pedido.aceptado","pedido.entregado"]}'
{ "id":"wh_3", "url":"https://tu-sistema.com/hook",
  "eventos":["pedido.aceptado","pedido.entregado"],
  "secreto_firma":"a1b2…(64 hex, se muestra UNA vez)", "activo":true }

이벤트: 스트림의 이벤트 + 와일드카드 pedido.* 및 *.  GET /webhooks 목록 · DEL /webhooks/{id} 삭제.

전달 및 서명

모든 전송에는 다음 헤더가 포함되며, 본문은 스트림의 객체와 동일합니다:

X-Elp-Evento: pedido.aceptado
X-Elp-Id: 84213            # úsalo como clave de idempotencia
X-Elp-Firma: <hmac_sha256_hex(secreto, cuerpo_crudo)>
X-Elp-Intento: 1
// Verificación (Node)
const firma = crypto.createHmac("sha256", SECRETO).update(rawBody).digest("hex");
if (firma !== req.headers["x-elp-firma"]) return res.sendStatus(401);
실패 시 재시도합니다(X-Elp-Intento가 증가). X-Elp-Id로 중복을 제거하세요.

주문 객체

/pedidos, /pedidos/{id}, 스트림 및 webhook이 반환하는 구조입니다. 예제의 고객 데이터는 익명 처리되었습니다. direccion/mesa/entrega/fiscal은 해당되지 않을 때 null입니다.

{
  "id":"ped_ni", "numero":"20260531-095",
  "tipo":"reparto",          // reparto|recogida|mesa
  "estado":"en_preparacion",
  "fuente":"web_publica",    // web_publica|tpv|manual|admin
  "creado_en":"2026-05-31T20:42:15Z", "aceptado_en":"…Z",
  "entregado_en":null, "programado_para":null,

  "restaurante":{ "id":"rest_1", "slug":"tu-restaurante", "nombre":"Tu Restaurante" },
  "cliente":{ "nombre":"Juan Pérez", "telefono":"+34 600 000 000",
    "email":"cliente@ejemplo.com", "consintio_marketing":false },
  "direccion":{ "linea":"Calle Mayor 22", "codigo_postal":null, "pais":"ES", "lat":38.154, "lng":-0.880 },
  "mesa":null,

  "items":[{ "id":"itm_A3", "producto_id":"prod_3K", "nombre":"Margarita",
    "tamaño":"mediana", "cantidad":1,
    "precio_unitario_cents":720, "opciones_total_cents":120, "total_cents":840,
    "estado_cocina":"pendiente",
    "opciones":[{ "id":"opc_5", "grupo":"Extras", "nombre":"Extra queso", "cantidad":1, "precio_cents":120 }] }],

  "totales":{ "moneda":"EUR", "subtotal_cents":840, "descuento_cents":0, "propina_cents":0,
    "tarifa_reparto_cents":100, "impuestos_cents":85, "total_cents":1025,
    "iva_desglose":[{ "tipo_porcentaje":10, "base_cents":940, "iva_cents":85 }] },
  "pago":{ "metodo":"online", "estado":"pagado", "proveedor":"stripe",
    "referencia_externa":"pi_3Td…", "pagos":[] },
  "entrega":{ "repartidor_nombre":null, "zona_id":"zon_a", "zona_nombre":"Granja de Rocamora", "tarifa_cents":100 },
  "fiscal":{ "factura_numero":"FA-1132/2026", "factura_fecha":"…Z", "factura_pdf":"https://…/factura.pdf" },
  "instrucciones":null
}

예제: 주방 TV 화면

독립 실행형 HTML+JS(읽기 전용): token을 붙여넣고 TV에서 열면 스트림을 통해 주문이 실시간으로 들어옵니다.

→ 주방 TV 예제 열기