Probar cuentas gestionadas con clave fact_test_
Recorre todo el flujo de provisión con una clave de pruebas: cuentas de pruebas, importación, lecturas y eventos, sin cobro ni reclamación.
Puedes ensayar todo el aprovisionamiento de cuentas de clientes con una clave fact_test_ antes de tocar un cliente real. No se cobra nada, no sale ningún vale ni correo, no interviene ninguna empresa real y nada llega a VeriFactu. Esta guía recorre el camino en cinco pasos, desde leer tu propia cuenta hasta leer los eventos de una cuenta de pruebas, y termina con lo que el camino no te deja hacer, para que sepas qué probar con una clave de producción.
Da por hecho que aprovisionas cuentas para tus clientes como describe cuentas gestionadas. Cómo se comporta una clave de pruebas en el resto de la API está en modo de prueba y sandbox.
Qué es una cuenta de pruebas
Una cuenta de pruebas es una cuenta gestionada creada con una clave fact_test_. Es una cuenta gestionada normal en el entorno test, con estas diferencias:
| Aspecto | Cómo funciona |
|---|---|
| Entorno | test. Es el entorno de la clave que la creó, no cambia nunca, y una cuenta de pruebas nunca pasa a ser de producción. |
| Quién la alcanza | Las claves fact_test_ de tu cuenta y la aplicación web en Modo pruebas. Una clave de producción responde 404 account_not_found, igual que con una cuenta que no es tuya. |
| NIF | El NIF que le das, como empresa sandbox sin ninguna empresa real detrás. |
| Estado | provisioned para siempre. No tiene titular ni vale, y nadie la reclama. |
| Coste | Ninguno. No hay ninguna llamada al proveedor de pago, no se pide método de pago y no cuenta para tu tope de cuentas gestionadas. paid_by_provider vale true porque tu cuenta es su pagadora, pero no se cobra nada. |
| Efectos | Ninguno en el mundo real. La empresa sandbox no envía ningún registro a VeriFactu ni ningún correo real. |
Antes de empezar
Necesitas tres cosas:
- El privilegio de proveedor.
accounts:readyaccounts:writeson scopes privilegiados que concedemos cuenta por cuenta, también para las cuentas de pruebas: consulta scopes privilegiados. Una cuenta en su trial puede crear cuentas de pruebas, y solo esas. - Una clave de pruebas. Créala en Ajustes → Desarrolladores → API Keys eligiendo el entorno de pruebas, o con una clave de producción mediante
POST /v1/accounts/{account}/api-keysconenvironmententest. Daleaccounts:readyaccounts:write, y ademáswebhooks:readpara el paso 5: es el único scope de webhooks que puede llevar una clave de pruebas. - Una
Idempotency-Keyen las escrituras irreversibles. Aprovisionar, aplicar una importación, cambiar el plan y terminar la gestión la necesitan también con una clave de pruebas, y una llamada sin ella responde422 idempotency_key_required.
El camino en una tabla
| Paso | Operación | Qué obtiene una clave de pruebas |
|---|---|---|
| 1. Lee tu cuenta | GET /v1/me | 200. Tu cuenta real, la clave con environment test, y tus cuentas de pruebas en client_accounts. |
| 2. Aprovisiona una cuenta de pruebas | POST /v1/accounts | 201 con environment test y sin vale. |
| 3. Importa un fichero de prueba | POST /v1/accounts/imports/preview y POST /v1/accounts/imports | 200 y 201. Las filas managed_account crean cuentas de pruebas y las filas own_nif salen ERROR. |
| 4. Opera la cuenta de pruebas | GET /v1/accounts/{account}, PATCH …/access-level, PATCH …/plan y DELETE …/management | 200, sin cobro. |
| 5. Lee sus eventos | GET …/webhooks y GET …/deliveries | 200. Entregas registradas, pending, nunca enviadas. |
1. Lee tu propia cuenta
Una clave fact_test_ pertenece a tu cuenta real, así que la lee como lo hace una clave de producción. Empieza preguntando qué es la clave. GET /v1/me no necesita ningún scope:
curl https://api.factuarea.com/v1/me \
-H "Authorization: Bearer $FACTUAREA_TEST_KEY"{
"data": {
"object": "me",
"account": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a00",
"name": "Asesoría Martínez",
"environment": "live",
"is_provider": true,
"privileged_scopes": [
"accounts:read",
"accounts:write"
]
},
"api_key": {
"name": "Pruebas de integración",
"prefix": "fact_test_1OSf9KdP",
"scopes": [
"accounts:read",
"accounts:write",
"webhooks:read"
],
"environment": "test"
},
"client_accounts": [],
"client_accounts_visible": true,
"client_accounts_has_more": false
}
}La respuesta está abreviada. Léela así:
- La clave es de pruebas, la cuenta es real.
api_key.environmentestestyaccount.environmenteslive. Elscopede la respuesta, que aquí no se muestra, lista la empresa sandbox que alcanza la clave, y solo esa. is_provideryprivileged_scopeste dicen si tienes el privilegio de proveedor. Sin él, el aprovisionamiento del paso 2 responde403 privileged_scope_required.client_accountslista solo tus cuentas de pruebas. Necesitaaccounts:readen vigor en la clave, o vuelve vacío conclient_accounts_visibleenfalse. El ejemplo está vacío porque todavía no existe ninguna cuenta de pruebas, y tras el paso 2 lista la nueva. Tus cuentas de producción no salen aquí: las listan las claves de producción.
Las demás lecturas de tu propia cuenta responden con una clave de pruebas como con una de producción, cada una con el scope de su operación y con los datos reales de tu cuenta: provisioning-usage, la cartera de NIF, los miembros y el consumo. Los webhooks y los registros de peticiones de la cuenta responden con los de tu entorno de pruebas.
Una clave de pruebas lee los datos reales de tu cuenta, como sus miembros y sus NIF, y nunca los cambia. Toda escritura sobre tu propia cuenta responde 403 live_credential_required: consulta lo que el camino no permite.
2. Aprovisiona una cuenta de pruebas
Aprovisiona con POST /v1/accounts y una clave de pruebas. Es la misma llamada que en producción, con el mismo cuerpo, y el entorno es el de la clave: nunca va en el cuerpo. Necesita accounts:write y una Idempotency-Key.
curl -X POST https://api.factuarea.com/v1/accounts \
-H "Authorization: Bearer $FACTUAREA_TEST_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"external_ref": "test-0001",
"plan": "empresario",
"access_level": "operate",
"tax_id": "B12345674",
"legal_name": "Talleres García SL"
}'{
"data": {
"id": "0199b2a0-3e44-7c31-8d10-4b1a2c3d4e01",
"object": "managed_account",
"external_ref": "test-0001",
"status": "provisioned",
"environment": "test",
"plan": "empresario",
"pending_plan": null,
"billing_interval": "monthly",
"access_level": "operate",
"display_name": "Talleres García SL",
"language": "es",
"companies": [
{
"id": "0199b2a0-3e44-7c31-8d10-4b1a2c3d4e02",
"tax_id": "B12345674",
"name": "Talleres García SL"
}
],
"claimed": false,
"claimed_at": null,
"management": {
"status": "active",
"ended_at": null
},
"paid_by_provider": true,
"created_at": "2026-09-30T10:00:00+00:00",
"claim_token": null,
"claim_url": null,
"claim_expires_at": null
}
}La respuesta es 201 Created con Location: /v1/accounts/{id}. Qué esperar, en comparación con una cuenta de producción:
- Sin vale.
claim_token,claim_urlyclaim_expires_atsonnull, y no sale ningún correo. No envíessend_email: una cuenta de pruebas no tiene ningún vale que entregar. owner_emailes opcional. Una cuenta de pruebas no tiene titular a quien invitar.- El NIF se valida como en producción. Necesita un NIF, CIF o NIE válido con su carácter de control.
- No cuenta para tu tope.
provisioning-usagela cuenta enmanaged_accounts.test, ylimityremainingno se mueven. Las comprobaciones de trial, de tope y de método de pago de una cuenta de producción no se ejecutan, así que un proveedor en su trial puede aprovisionar cuentas de pruebas. - La llamada es idempotente por
external_ref. Repetirla responde200con la misma cuenta y no crea nada.
El external_ref pertenece a tu cuenta en los dos entornos. Reutilizar uno que tiene una cuenta de producción responde 409 managed_account_external_ref_in_other_environment, y al revés. Mantén tus referencias de pruebas separadas de las de producción, por ejemplo con un prefijo test-.
Los errores que puedes encontrar aquí son los de aprovisionar una cuenta de producción que no dependen de un cobro:
| Código | Estado | Cuándo |
|---|---|---|
privileged_scope_required | 403 | Tu cuenta no tiene el privilegio de proveedor, o la persona que emitió la clave ya no es titular ni administradora de ella. |
invalid_param_value | 422 | Un campo no pasa la validación, por ejemplo un tax_id sin carácter de control válido. error.param lo nombra. |
managed_account_plan_not_self_serve | 422 | plan es enterprise, que solo asignamos nosotros por contrato. |
managed_account_external_ref_in_other_environment | 409 | El external_ref nombra una cuenta de producción. |
idempotency_key_required | 422 | La petición no lleva Idempotency-Key. |
3. Importa un fichero de prueba
La importación masiva funciona con una clave de pruebas en dos llamadas: una vista previa sin efectos y la aplicación. El entorno es, otra vez, el de la clave. Pruébala con un fichero de tres filas, separado por punto y coma y con las columnas de la plantilla:
mode;external_ref;plan;tax_id;legal_name;owner_email
managed_account;test-0002;emprendedor;A58818501;Bodega Sol SL;
managed_account;test-0003;empresario;B28013829;Horno Mar SL;hugo@hornomar.example
own_nif;;;B76543214;Delegación Este SL;Previsualízalo primero. La vista previa es un POST porque sube el fichero, no escribe nada y no necesita Idempotency-Key:
curl -X POST https://api.factuarea.com/v1/accounts/imports/preview \
-H "Authorization: Bearer $FACTUAREA_TEST_KEY" \
-F "accounts_file=@clients.csv"{
"data": {
"object": "managed_account_import_preview",
"rows": [
{
"line": 2,
"mode": "managed_account",
"external_ref": "test-0002",
"tax_id": "A58818501",
"status": "VALID",
"code": null,
"errors": {},
"plan": "emprendedor",
"monthly_amount_cents": 0,
"proration_amount_cents": 0
},
{
"line": 3,
"mode": "managed_account",
"external_ref": "test-0003",
"tax_id": "B28013829",
"status": "VALID",
"code": null,
"errors": {},
"plan": "empresario",
"monthly_amount_cents": 0,
"proration_amount_cents": 0
},
{
"line": 4,
"mode": "own_nif",
"external_ref": null,
"tax_id": "B76543214",
"status": "ERROR",
"code": "live_credential_required",
"errors": {},
"plan": null,
"monthly_amount_cents": 0,
"proration_amount_cents": 0
}
],
"totals": {
"total_rows": 3,
"valid": 2,
"warning": 0,
"already_exists": 0,
"blocked": 0,
"error": 1
},
"cost": {
"currency": "EUR",
"total": {
"monthly_amount_cents": 0,
"proration_amount_cents": 0
}
},
"own_company_customers": null
}
}La respuesta está abreviada: las filas llevan más campos y cost también se desglosa por modalidad. Con una clave de pruebas:
- Las filas
managed_accountsonVALIDy crearían cuentas de pruebas, sin vale. - La fila
own_nifesERRORconcodelive_credential_required: un NIF de tu propia cuenta se da de alta solo con una clave de producción. La fila de opciones de la importación, la que aplica los clientes a tu propia empresa, sale igual. - El coste es
0. El total no cuenta ni la cuota mensual ni el prorrateo, y ninguna llamada llega al proveedor de pago.
Aplica el mismo fichero con POST /v1/accounts/imports. Necesita una Idempotency-Key:
curl -X POST https://api.factuarea.com/v1/accounts/imports \
-H "Authorization: Bearer $FACTUAREA_TEST_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F "accounts_file=@clients.csv"La respuesta es 201 Created con el resultado de la ejecución, abreviado aquí:
{
"data": {
"id": "0199b2a0-5f60-7d40-9e20-6d3c4e5f6a05",
"object": "managed_account_import",
"status": "completed",
"stats": {
"total_rows": 3,
"valid": 2,
"warning": 0,
"already_exists": 0,
"blocked": 0,
"error": 1,
"created": 2,
"reconciled": 0,
"customers_queued": 0,
"monthly_amount_cents": 0,
"proration_amount_cents": 0
},
"rows": [
{
"line": 2,
"mode": "managed_account",
"external_ref": "test-0002",
"status": "VALID",
"account_id": "0199b2a0-5f66-7d42-9e21-5c2b3d4e5f03",
"claim_token": null,
"claim_url": null
}
],
"own_company_customers": null
}
}Se crean dos cuentas y la fila own_nif no crea nada. Ninguna fila lleva un vale. Aplica el mismo fichero otra vez para ver la reconciliación: las dos cuentas salen ALREADY_EXISTS y no se crea nada dos veces. Las columnas, los límites y los estados de fila son los de la importación masiva.
4. Opera la cuenta de pruebas
Las operaciones de aprovisionamiento nombran la cuenta de pruebas por su id en el segmento {account}. Con una clave de pruebas, tu cuenta alcanza las cuentas de pruebas que aprovisionó y ninguna otra.
- Léela.
GET /v1/accounts/{account}responde200con la cuenta como en el paso 2, ycompanies[]lista su NIF.GET /v1/accountslista solo cuentas de pruebas con una clave de pruebas. Una clave de producción responde404 account_not_foundcon elidde una cuenta de pruebas. - Cambia tu nivel.
PATCH /v1/accounts/{account}/access-levelconlevelresponde200con el nuevoaccess_level. Una cuenta de pruebas nunca se reclama, así que puedes subir y bajar el nivel tantas veces como quieras. - Cambia el plan.
GET /v1/accounts/{account}/plan/previewconplanmuestra los dos importes a0, yPATCH /v1/accounts/{account}/plancambia el plan en el acto y sin cobro. Las dos piden el niveloperate, y el cambio necesita unaIdempotency-Key. El precio de las cuentas gestionadas explica el flujo de producción. - Termina la gestión.
DELETE /v1/accounts/{account}/managementresponde200conmanagement.statusenended, y desde tu siguiente petición la cuenta responde404, como una de producción: consulta termina la gestión.
curl -X PATCH https://api.factuarea.com/v1/accounts/0199b2a0-3e44-7c31-8d10-4b1a2c3d4e01/access-level \
-H "Authorization: Bearer $FACTUAREA_TEST_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{ "level": "view" }'Los datos del NIF de una cuenta de pruebas, como sus facturas y sus contactos, no se alcanzan con una clave. Una clave fact_test_ alcanza solo la empresa sandbox de tu propia cuenta, así que /v1/companies/{company}/… con el id de companies[] responde 404 profile_not_found. Para trabajar con esos datos, pasa la aplicación web a Modo pruebas con el interruptor de modo pruebas de la cabecera: tus cuentas de pruebas aparecen entre tus cuentas de clientes, y al elegir una, su empresa sandbox pasa a ser la activa.
5. Lee sus eventos en un endpoint de pruebas
Los eventos de una cuenta de pruebas no llegan nunca a un endpoint de producción, y un endpoint del entorno test no recibe nunca los eventos de una cuenta de producción. Para seguir el camino necesitas un endpoint de pruebas de tu cuenta, y una clave de pruebas no puede crearlo: lo creas en la aplicación web.
- Pasa la aplicación web a Modo pruebas con el interruptor de modo pruebas de la cabecera. Tienes que ser titular o administrador de la cuenta.
- Abre Ajustes → Desarrolladores → Webhooks y elige Cuenta en el selector Empresa | Cuenta.
- Elige Nuevo endpoint de cuenta. Escribe una URL HTTPS, deja Cuentas de las que recibe eventos en Todas, y elige los eventos que quieras en Eventos suscritos:
account.managed_account_provisionedpara el paso 2,account.import_completedpara el paso 3, yaccount.access_level_changedyaccount.management_endedpara el paso 4. El secreto de firma se muestra una sola vez.
El endpoint toma el entorno de la sesión: es test, no cambia nunca y es invisible desde producción. El número de endpoints depende del plan y se cuenta por cuenta y entorno. Cuando el plan no tiene ninguno, o llegas al límite, la aplicación rechaza el endpoint con addon_required o account_webhook_endpoint_limit_reached: consulta webhooks de cuenta.
Ahora repite los pasos 2 a 4 con tu clave de pruebas y lee lo que pasó. Con webhooks:read, una clave de pruebas lee los endpoints y las entregas del entorno de pruebas:
curl https://api.factuarea.com/v1/accounts/$ACCOUNT_ID/webhooks \
-H "Authorization: Bearer $FACTUAREA_TEST_KEY"La respuesta lista tus endpoints de pruebas, y solo esos. Toma el id del tuyo y lista sus entregas con GET /v1/accounts/{account}/webhooks/{webhook}/deliveries, donde {account} es tu propio account.id:
{
"data": [
{
"id": "0199b2a0-3e80-7c55-8d41-8f5e6a7b8c07",
"object": "account_webhook_delivery",
"event_id": "0199b2a0-3e7a-7c50-8d40-9a6f7b8c9d08",
"event_type": "account.managed_account_provisioned",
"event_source": "account",
"company_id": null,
"account_relationship": "own",
"environment": "test",
"status": "pending",
"attempt": 0,
"manual_retry_count": 0,
"next_retry_at": null,
"response_status": null,
"response_body": null,
"duration_ms": null,
"payload": {
"id": "0199b2a0-3e7a-7c50-8d40-9a6f7b8c9d08",
"type": "account.managed_account_provisioned",
"livemode": false,
"account": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a00"
},
"account_relationship": "own",
"company_id": null,
"data": {
"type": "account.managed_account_provisioned",
"object": {
"object": "account_relation",
"id": "0199b2a0-3e46-7c33-8d12-0b7a8c9dae09",
"origin": "provisioned",
"level": "operate",
"previous_level": null,
"grantor_account_id": "0199b2a0-3e44-7c31-8d10-4b1a2c3d4e01",
"grantee_account_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a00",
"status": "active",
"managed_account_id": "0199b2a0-3e44-7c31-8d10-4b1a2c3d4e01",
"external_ref": "test-0001"
}
}
},
"created_at": "2026-09-30T10:00:01+00:00"
}
],
"has_more": false,
"next_cursor": null
}La entrega está abreviada. Su payload es el sobre que recibiría un endpoint de producción, con livemode en false. Qué hace distinto a un endpoint de pruebas:
- No se envía nada a tu URL. La entrega de un endpoint de pruebas se registra y no sale nunca de Factuarea, así que queda
pendingconattempten0. La lees aquí, o en el detalle del endpoint de la aplicación web, y no hay ninguna petición que verificar. - Solo llegan los eventos de una cuenta de pruebas. El entorno de un evento
account.*es el de la cuenta a la que se refiere. Los eventos de una cuenta de producción no llegan nunca a este endpoint, y un endpoint de producción no recibe nunca los eventos de tus cuentas de pruebas.
Lee una sola entrega con GET …/deliveries/{delivery}, que la devuelve con el mismo payload. Las lecturas de los webhooks de cuenta conservan sus guardas con una clave de pruebas: la persona que emitió la clave tiene que ser hoy titular o administradora de la cuenta, como explica webhooks de cuenta.
Lo que el camino no permite
| Lo que intentas | Qué obtiene una clave de pruebas | Qué hacer |
|---|---|---|
| Una escritura sobre tu propia cuenta de producción: equipo, invitaciones, titularidad, API keys, cartera de NIF, traspasos de NIF o asientos de empleado | 403 live_credential_required, sin escribir nada | Usa una clave fact_live_. Las lecturas de tu cuenta funcionan con la clave de pruebas. |
| Una escritura sobre una cuenta gestionada de producción | 404 account_not_found | Una clave de pruebas alcanza solo cuentas de pruebas, y una de producción solo cuentas de producción. |
| Crear, editar, probar o borrar un endpoint de webhook de cuenta, rotar su secreto o reintentar una entrega | 403: insufficient_scope porque una clave de pruebas no puede llevar webhooks:write, o module_not_available_in_sandbox si lo lleva de todos modos. El MCP responde live_credential_required. | Crea el endpoint de pruebas en la aplicación web en Modo pruebas, como en el paso 5. |
Las filas own_nif de una importación, y su fila de opciones | La fila sale ERROR con code live_credential_required, no crea nada y suma 0 a los totales | Importa esas filas con una clave de producción. |
| Reemitir el vale de una cuenta de pruebas, o reclamarla | 422 managed_account_not_claimable. Una cuenta de pruebas no tiene vale, ni enlace de reclamación, ni titular. | Nada: se queda provisioned para siempre. |
| Pasar una cuenta de pruebas a producción | Ninguna operación lo hace, y una cuenta de pruebas no cambia nunca de entorno. | Aprovisiona una cuenta de producción con una clave fact_live_ y otro external_ref. Nada pasa de un entorno al otro. |
| Ver un cobro, un prorrateo o un error de pago | No se cobra nada, no se pide método de pago y la vista previa del plan muestra 0. Las comprobaciones de tu trial, de tu tope de cuentas gestionadas y de tu método de pago no se ejecutan. | Prueba el cobro con una cuenta de producción: consulta precio y pagador. |
| Enviar a VeriFactu, o subir el certificado del cliente | La empresa sandbox no tiene efectos fiscales y el módulo VeriFactu no está disponible en modo de prueba. Tampoco sale ningún correo real. | Sigue el certificado VeriFactu del cliente con una cuenta de producción. |
| Trabajar con los datos del NIF de una cuenta de pruebas por la API | 404 profile_not_found en /v1/companies/{company}/… | Usa la aplicación web en Modo pruebas, como en el paso 4. |
Pasar a producción
Una cuenta de pruebas y una cuenta de producción son independientes, y nada de lo que creaste con la clave de pruebas pasa a producción. Para pasar a producción:
- Aprovisiona las cuentas de producción con una clave
fact_live_. Una cuenta de producción necesitaowner_email, un método de pago en tu cuenta y margen bajo tu tope, y se cobra prorrateada en el acto: consulta precio y pagador. - Dale a cada una un
external_refnuevo. El de una cuenta de pruebas responde409desde el lado de producción. - Crea un endpoint de producción para los eventos de producción. El endpoint de pruebas no los recibe nunca. Créalo con una clave de producción o en la aplicación web en modo Producción.
Relacionado
aprovisiona cuentas para tus clientes, el vale de reclamación, tu nivel y el fin de la gestión.
lo que pagas por cada cuenta gestionada de producción y cómo se cobra un cambio de plan.
las columnas, las modalidades, los estados de fila y los límites de la importación.
los endpoints, los eventos y el sobre de tu cuenta y de sus NIF.
qué hace una clave fact_test_ en el resto de la API.
todos los códigos del modelo de cuentas, con su causa y qué hacer.