presupuestaIA · API pública

API pública de presupuestaIA

API REST de solo lectura que expone los datos sincronizados de cada empresa (clientes, artículos, obras y avisos correctivo). Pensada para integraciones con ERPs externos, paneles BI o procesos automáticos. Una API key habilita el acceso a una empresa concreta; los datos están aislados por empresa.

REST · JSON Read-only Bearer auth Datos por empresa

Base URL

https://bydakfftxdorkkswixoa.supabase.co/functions/v1/api-public-v1
🧪

Sandbox de pruebas

Antes de pedir tu API key real, puedes probar tu integración contra endpoints sandbox que devuelven datos ficticios fijos y no requieren autenticación. Útil para desarrollar y validar que tu código procesa bien la respuesta antes de pasar a producción.

GET /v1/sandbox/clientes
GET /v1/sandbox/articulos
GET /v1/sandbox/obras
GET /v1/sandbox/avisos-correctivo

Pruébalo ya — copia y pega:

curl https://bydakfftxdorkkswixoa.supabase.co/functions/v1/api-public-v1/v1/sandbox/clientes

O ábrelo en el navegador:

🌐 Abrir /v1/sandbox/clientes

Cuando funcione, pasa a producción:

  1. Pide tu API key real al admin de tu empresa (panel Integraciones).
  2. Cambia la URL: /v1/sandbox/clientes → /v1/clientes.
  3. Añade el header: Authorization: Bearer pia_…

Las respuestas reales tienen el mismo formato que las del sandbox. Solo cambia el contenido (datos reales en vez de ficticios) y desaparece el flag "sandbox": true.

Autenticación

Cada llamada debe enviar la API key de la empresa en el header Authorization. La key te la entregará el administrador de la empresa una sola vez al generarla, con formato pia_<prefix>_<secret>.

Authorization: Bearer pia_a1b2c3d4_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Alternativa equivalente: header X-API-Key: pia_….

⚠️ La key concede acceso a todos los datos de la empresa. Trátala como una contraseña: no la subas a un repositorio público, no la compartas por email, y revócala si crees que se ha filtrado.

Endpoints

📦 Acceso completo a TODOS los campos

Cada item devuelto incluye los campos destacados normalizados (cómodos para usar) más el objeto data con la fila íntegra original proveniente del ERP (~150 columnas en clientes, etc.). Esto significa que no hay ningún campo del ERP que quede fuera del API: si no aparece en los campos destacados, lo encuentras dentro de data.

GET /v1/clientes · listado

Lista los clientes sincronizados de la empresa.

Cada item:

{
  "id_velneo": "string",
  "nombre": "string",
  "cif": "string",
  "email": "string",
  "telefono": "string",
  "direccion": "string",
  "data": { /* fila íntegra del ERP, ~150 campos:
              "01_NOMBRE_COMERCIAL", "06_CIF", "07_DOMICILIO",
              "08_CIUDAD", "09_PROVINCIA", "12_CPOSTAL",
              "WWW", "PORCENTAJE_RETENCION", … */ },
  "actualizado_at": "ISO 8601 timestamp"
}
GET /v1/clientes/:id_velneo · detalle

Devuelve un cliente concreto con todos sus campos. :id_velneo es el ID del ERP.

{
  "ok": true,
  "item": { /* mismo formato que en el listado, con `data` íntegro */ }
}
GET /v1/articulos · listado · detalle en /v1/articulos/:id_velneo

Catálogo de artículos sincronizado.

{
  "id_velneo": "string",
  "codigo": "string",
  "nombre": "string",
  "unidad": "string",
  "precio": "number",
  "data": { /* todas las columnas del ERP: familia, proveedor, marca,
              stock mínimo/máximo, ecotasa, precios margen,
              fotos, observaciones, … */ },
  "actualizado_at": "ISO 8601 timestamp"
}
GET /v1/obras · listado · detalle en /v1/obras/:id_velneo

Listado de obras de la empresa.

{
  "id_velneo": "string",
  "codigo": "string",
  "nombre": "string",
  "descripcion": "string",
  "cliente_id_velneo": "string",
  "estado": "string",
  "data": { /* todos los campos: importes presupuestados/reales,
              fechas, contactos, dirección, persona de contacto,
              documentos, etc. */ },
  "actualizado_at": "ISO 8601 timestamp"
}
GET /v1/avisos-correctivo · listado · detalle en /v1/avisos-correctivo/:id_velneo

Avisos / partes correctivos.

{
  "id_velneo": "string",
  "codigo": "string",
  "fecha": "YYYY-MM-DD",
  "cliente_id_velneo": "string",
  "obra_id_velneo": "string",
  "descripcion": "string",
  "estado": "string",
  "prioridad": "string",
  "data": { /* todos los campos: técnico asignado, hora cita,
              coste mano de obra, coste material, contrato
              mantenimiento, ruta, etc. */ },
  "actualizado_at": "ISO 8601 timestamp"
}

Parámetros de query

Todos los endpoints aceptan los mismos parámetros opcionales:

Parámetro Tipo Por defecto Descripción
limitint (1-1000)100Tamaño de página
offsetint0Para paginar tras el primer batch
updated_sinceISO 8601—Solo registros modificados desde esa fecha (sync incremental)

Formato de respuesta

Listados:

{
  "ok": true,
  "total": 1268,
  "limit": 100,
  "offset": 0,
  "has_more": true,
  "next_offset": 100,
  "items": [ /* … */ ]
}

total es el total de registros disponibles tras aplicar filtros (no la cuenta de items). Para iterar todo basta seguir next_offset mientras has_more sea true.

Detalle (/v1/<recurso>/:id_velneo):

{
  "ok": true,
  "item": { /* el registro con `data` íntegro */ }
}

Códigos de error

HTTP error Causa
401auth_requiredFalta header Authorization
401unauthorizedKey inválida o revocada
404not_foundEndpoint inexistente
405method_not_allowedSolo se permite GET
500—Error interno; reintentar tras unos segundos

Ejemplos

curl · listado

curl -H "Authorization: Bearer pia_a1b2c3d4_xxxxxxxxxxxx" \
  "https://bydakfftxdorkkswixoa.supabase.co/functions/v1/api-public-v1/v1/clientes?limit=50"

curl · detalle de un cliente

curl -H "Authorization: Bearer pia_a1b2c3d4_xxxxxxxxxxxx" \
  "https://bydakfftxdorkkswixoa.supabase.co/functions/v1/api-public-v1/v1/clientes/1234"

Devuelve item.data con TODAS las columnas originales del ERP.

Sync incremental (solo cambios de hoy)

curl -H "Authorization: Bearer pia_a1b2c3d4_xxxxxxxxxxxx" \
  "https://bydakfftxdorkkswixoa.supabase.co/functions/v1/api-public-v1/v1/avisos-correctivo?updated_since=2026-05-06T00:00:00Z"

Paginación completa (Node.js)

const KEY = process.env.PIA_API_KEY
const BASE = 'https://bydakfftxdorkkswixoa.supabase.co/functions/v1/api-public-v1'

async function obtenerTodos(recurso) {
  const items = []
  let offset = 0
  while (true) {
    const r = await fetch(`${BASE}/v1/${recurso}?limit=1000&offset=${offset}`, {
      headers: { Authorization: `Bearer ${KEY}` },
    })
    if (!r.ok) throw new Error(`HTTP ${r.status}`)
    const { items: batch, has_more, next_offset } = await r.json()
    items.push(...batch)
    if (!has_more) break
    offset = next_offset
  }
  return items
}

const clientes = await obtenerTodos('clientes')
console.log(`${clientes.length} clientes`)
// Acceder a cualquier campo Velneo:
console.log(clientes[0].data['07_DOMICILIO'], clientes[0].data['12_CPOSTAL'])

Python (requests)

import os, requests

KEY = os.environ['PIA_API_KEY']
BASE = 'https://bydakfftxdorkkswixoa.supabase.co/functions/v1/api-public-v1'

r = requests.get(
    f'{BASE}/v1/articulos',
    headers={'Authorization': f'Bearer {KEY}'},
    params={'limit': 500},
)
r.raise_for_status()
print(r.json()['total'], 'artículos disponibles')

Frecuencia de actualización

Los datos se actualizan cuando el administrador de la empresa sube los CSV exportados de su ERP desde el panel de gestión (sustituye por completo el contenido anterior). Usa el campo actualizado_at o el parámetro updated_since para detectar cambios.

Buenas prácticas

¿Dudas o necesitas más endpoints? Contacta con tecomed@phoneia.es.