API REST: escribir datos
Crear, editar y borrar registros con POST /api/writeoperations: los parámetros, las cuatro formas del cuerpo, los valores, los límites de un lote y la respuesta.
POST /api/writeoperations escribe en una sección. La URL, el token y los límites son los de toda la API: Referencia de la API REST.
Antes de empezar
- El token Bearer de una clave API que no sea de Solo lectura: El token Bearer.
- La sección, en Leer y escribir si la clave limita secciones.
Qué hace
Crea, edita y borra registros de una sección. Cómo se comporta el servidor al escribir (autorrellenado, orden de los campos, scripts): Escribir en secciones.
Parámetros de la URL
| Parámetro | Tipo | Qué hace |
|---|---|---|
sectionId | GUID | La sección. Obligatorio. Las de fábrica: Secciones del núcleo. |
FieldPrimary | texto | El campo que identifica el registro, normalmente id. Obligatorio. |
scripts | booleano | Con true ejecuta los scripts de la sección al guardar, como la interfaz. Guarda un registro cada vez, con 100 ms entre uno y otro (un lote de 25 tarda al menos 2,5 segundos), en una cola común a todas las peticiones. Con false, por defecto, escribe el lote de una vez. |
El cuerpo es obligatorio, con Content-Type: application/json; sin esa cabecera, 415.
Crear, editar y borrar
id | Operación |
|---|---|
"" o ausente | Alta. Dinaup asigna el ID y lo devuelve en rowID. |
| Un GUID existente | Edición de los campos que envías. Los demás no se tocan. |
No hay DELETE: un borrado es una edición con eliminado a "1".
{ "id": "123e4567-e89b-12d3-a456-426614174000", "eliminado": "1" }Al borrar, scripts va en false
Deja scripts fuera de la URL en toda petición que ponga eliminado a "1".
Los valores
Cada campo se nombra por su columna, pr_XXXXXXXXX, tal como sale en Desarrollo → Esquema (Esquema) y en MyDinaup. Todos los valores viajan como texto:
| Tipo | Formato | Ejemplo |
|---|---|---|
| Decimal | Punto decimal, sin separador de miles | "1234.5" |
| Entero | Dígitos | "42" |
| Booleano | 1 o 0 | "1" |
| Fecha y hora | yyyy-MM-dd HH:mm:ss, en UTC | "2026-08-10 14:30:00" |
| Fecha | yyyy-MM-dd | "2026-08-10" |
| Hora | HH:mm:ss | "14:30:00" |
| Referencia a otro registro | Su GUID, "" para dejarla vacía, o [campo=valor] para buscar el registro por nombre o por una columna pr_... | "123e4567-...", "[nombre=Kilogramos]" |
Un número JSON llega como su texto y null llega vacío. true y false llegan como True y False, que un booleano no acepta: usa "1" y "0". El servidor quita los espacios de los extremos.
Estos campos los pone el servidor; si los envías, se descartan sin error:
fecha · fecham · fechaia · fechasyn · modificado · plantillapid · usuarioid · ubicacionid · ubicacionLas cuatro formas del cuerpo
Un registro:
{ "id": "", "pr_cliente": "<id-del-cliente>", "pr_importe": "100.00" }Un registro con sus líneas (Main y List), en secciones con tabla de líneas como una venta:
{
"Main": { "id": "", "pr_cliente": "<id-del-cliente>" },
"List": [
{ "pr_item": "<id-del-producto>", "pr_cantidad": "10" },
{ "pr_item": "<id-del-producto>", "pr_cantidad": "20" }
]
}Un lote: una lista de cualquiera de las dos formas anteriores.
[
{ "id": "", "pr_campo": "valor1" },
{ "id": "", "pr_campo": "valor2" }
]Un objeto es un registro con líneas cuando tiene Main y List, con la inicial en mayúscula. En un lote, el primer objeto decide la forma de todos. Otro tipo de cuerpo responde 400 con Invalid data format.
Límites de un lote
| Límite | Valor |
|---|---|
| Operaciones por petición | 25 |
| Operaciones más líneas, en total | 2.500 |
| Lista vacía | 400 con Invalid data format. |
| Juego de campos | Todos los objetos llevan los mismos campos, y todas las líneas también. |
Un lote que pasa de un tope o mezcla juegos de campos falla entero con 400, sin escribir nada. Si un campo no aplica a un objeto, envíalo vacío o separa los objetos en peticiones distintas. En una edición, el vacío borra lo que el registro tuviera.
Petición
curl -X POST "https://<clave-de-conexion>.dinaup.io/api/writeoperations?sectionId=<id-de-la-seccion>&FieldPrimary=id&scripts=true" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d "{\"id\": \"\", \"pr_cliente\": \"<id-del-cliente>\", \"pr_importe\": \"100.00\"}"Respuesta
Un registro devuelve un objeto; un lote, una lista con un objeto por registro:
{
"sectionID": "...",
"aError": "",
"description": null,
"dynamicDocumentResult": "",
"optimized": false,
"rowID": "123e4567-e89b-12d3-a456-426614174000",
"tokenID": "...",
"confirmed": true,
"isAdded": true,
"dateResult": "2026-09-23T10:00:00.0000000Z"
}| Campo | Qué dice |
|---|---|
confirmed | La fila se guardó. |
aError | El motivo del fallo de esa fila. Vacío si fue bien. |
rowID | El ID del registro; en un alta, el que asignó Dinaup. |
isAdded | true si se creó, false si se editó. |
Estos errores paran la petición entera con 400 antes de escribir nada, también en un lote:
- Un campo que no existe en la sección.
- Un valor que no cumple el formato de su tipo o pasa del largo máximo del campo.
- Con
FieldPrimary=id, unidque no es un GUID o que no existe. - Una referencia a un registro que no existe o está eliminado.
- Un enlace
[campo=valor]que no encuentra ninguna fila.
Si el servidor rechaza una fila al guardarla, un registro suelto falla entero con 500 y el motivo; en un lote, las demás filas se escriben y la respuesta es 200.
En un lote, el código de respuesta no basta
Comprueba confirmed y aError de cada resultado. Reintenta solo las filas con aError: repetir el lote entero duplica las que sí entraron.
Las escrituras respetan los permisos de la clave: si su empleado no puede escribir en la sección, la operación falla con el motivo.