Emisores, establecimientos y puntos de emisión
Un emisor es un contribuyente (RUC) que emite comprobantes. Una cuenta puede tener varios emisores. Cada emisor tiene establecimientos (códigos de tres dígitos como 001, tal como constan en el RUC) y cada establecimiento tiene puntos de emisión (001, 002, …). Junto con el secuencial forman el número del comprobante: 001-001-000000123.
Administrar emisores, establecimientos y puntos de emisión por la API requiere una llave read_write con alcance account, también para leerlos. La consola administra los mismos recursos en Emisores, y en ella un emisor solo se agrega desde su certificado (Nuevo emisor).
| Operación | Endpoint |
|---|---|
Crear un emisor desde su certificado .p12 |
POST /v1/issuer-onboardings, GET /v1/issuer-onboardings/{onboardingId}, POST .../{onboardingId}/complete |
| Crear, listar emisores | POST, GET /v1/issuers |
| Leer, actualizar, eliminar un emisor | GET, PATCH, DELETE /v1/issuers/{issuerId} |
| Crear, listar establecimientos | POST, GET /v1/issuers/{issuerId}/establishments |
| Leer, actualizar, eliminar un establecimiento | GET, PATCH, DELETE /v1/issuers/{issuerId}/establishments/{establishmentId} |
| Crear, listar puntos de emisión | POST, GET .../establishments/{establishmentId}/emission-points |
| Leer, eliminar un punto de emisión | GET, DELETE .../emission-points/{emissionPointId} |
Crear un emisor desde su certificado
Sección titulada «Crear un emisor desde su certificado»La forma más corta de agregar un emisor es subir solo su firma electrónica (.p12) y su contraseña. Flashpi verifica el certificado, lee de él el RUC y el titular, te propone el RUC y la razón social para que revises y completes el perfil tributario y, al completar, crea el emisor con su establecimiento 001 y su punto de emisión 001. El mismo certificado sirve para pruebas y producción, así que no hace falta subirlo dos veces. La consola hace estos pasos en Emisores, Nuevo emisor.
Funciona con una llave read_write con alcance account de cualquier ambiente.
1. Sube el certificado
Sección titulada «1. Sube el certificado»curl https://api.flashpi.com.ec/v1/issuer-onboardings \ -H "Authorization: Bearer $FLASHPI_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -F "file=@signature.p12" \ -F "password=$P12_PASSWORD"El archivo y la contraseña tienen los mismos límites que en la carga de un certificado y se cifran apenas llegan; la huella de la Idempotency-Key no incluye la contraseña. La respuesta es 202 Accepted, con el encabezado Location del alta, que empieza en verifying:
{ "id": "01a0fd70-2b4c-7d1e-9f3a-5c6b7d8e9f01", "status": "verifying", "expiresAt": "2026-10-08T16:20:31.000Z", "rejection": null, "certificate": null, "proposedRuc": null, "rucNeedsConfirmation": false, "existingIssuer": null, "sri": null, "prefill": null, "completed": null, "createdAt": "2026-10-02T16:20:31.000Z", "updatedAt": "2026-10-02T16:20:31.000Z"}2. Consulta el alta hasta que esté lista
Sección titulada «2. Consulta el alta hasta que esté lista»curl https://api.flashpi.com.ec/v1/issuer-onboardings/01a0fd70-2b4c-7d1e-9f3a-5c6b7d8e9f01 \ -H "Authorization: Bearer $FLASHPI_API_KEY"Vuelve a leerla cada pocos segundos mientras su status sea verifying (la verificación suele tardar menos de un minuto):
status |
Qué significa |
|---|---|
verifying |
Flashpi verifica la contraseña, la clave de firma, la vigencia, la cadena y la revocación, como en la verificación de un certificado. |
ready |
El certificado es válido: el alta trae sus datos y se puede completar. |
rejected |
rejection.code y rejection.message dicen por qué, con los mismos códigos que un certificado rechazado. Corrige la causa e inicia otra alta. |
completed |
Ya se completó; completed tiene los ID del emisor y del certificado. |
expired |
No se completó en 6 días y ya no se puede completar; su archivo cifrado se elimina automáticamente poco después (unos 7 días después de subirlo). Inicia otra alta. |
Flashpi elimina un alta 30 días después de que se completa, vence o se rechaza; desde entonces GET /v1/issuer-onboardings/{onboardingId} responde 404 not_found. Guarda los ID de la respuesta de complete, o lee el emisor con GET /v1/issuers/{issuerId}, en lugar de volver a leer el alta.
Un alta lista de una empresa:
{ "id": "01a0fd70-2b4c-7d1e-9f3a-5c6b7d8e9f01", "status": "ready", "expiresAt": "2026-10-08T16:20:31.000Z", "rejection": null, "certificate": { "serialNumber": "4f2a9c01", "validFrom": "2026-09-30T15:00:00.000Z", "validTo": "2028-09-29T15:00:00.000Z", "issuingCa": { "code": "SECURITY_DATA", "displayName": "Security Data" }, "holder": { "commonName": "MARIA FERNANDA TORRES", "organization": "TOSTADURIA ANDINA S.A." }, "identification": { "ruc": "1790000000001", "rucSource": "certificate", "cedula": null } }, "proposedRuc": "1790000000001", "rucNeedsConfirmation": false, "existingIssuer": null, "sri": { "status": "disabled", "fetchedAt": null, "profile": null, "warnings": [] }, "prefill": { "ruc": "1790000000001", "legalName": "TOSTADURIA ANDINA S.A.", "tradeName": null, "headOfficeAddress": null, "taxProfile": { "keepsAccounting": null, "rimpeRegime": null, "specialTaxpayer": null, "withholdingAgent": null } }, "completed": null, "createdAt": "2026-10-02T16:20:31.000Z", "updatedAt": "2026-10-02T16:20:40.000Z"}| Campo | Notas |
|---|---|
certificate |
Datos públicos del certificado, sin material de firma: su serie, su vigencia, la entidad que lo emitió, el titular (commonName) y su empresa (organization), y la identificación que trae. |
proposedRuc, rucNeedsConfirmation |
El RUC con el que se completa. Cuando no viene del propio certificado, rucNeedsConfirmation es true y debes confirmarlo (consulta RUC de una persona natural). proposedRuc es null cuando el certificado no trae un RUC ni una cédula (consulta Certificado sin RUC). |
existingIssuer |
El emisor de tu cuenta que ya tiene ese RUC, si existe: completar renueva su certificado (consulta Renovación). |
sri |
La consulta al registro de RUC del SRI, hoy desactivada (status: "disabled"). Consulta Datos del SRI. |
prefill |
Los valores para empezar el perfil: el RUC y la razón social, que es la organization del certificado de una empresa o el commonName de una persona. El nombre comercial, la dirección matriz y el perfil tributario solo vienen del SRI, así que hoy son null y los escribes tú. null donde no se sabe nada. |
3. Completa el alta
Sección titulada «3. Completa el alta»Envía el emisor con los mismos campos que Crear un emisor, partiendo de prefill, corrigiendo lo que haga falta y completando lo que falte. Los números de resolución de contribuyente especial y de agente de retención los escribes tú.
curl https://api.flashpi.com.ec/v1/issuer-onboardings/01a0fd70-2b4c-7d1e-9f3a-5c6b7d8e9f01/complete \ -H "Authorization: Bearer $FLASHPI_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "legalName": "TOSTADURIA ANDINA S.A.", "tradeName": "Café Andino", "headOfficeAddress": "Av. Amazonas N36-152 y Naciones Unidas, Quito", "taxProfile": { "keepsAccounting": true, "withholdingAgentResolution": "6498", "rimpeRegime": null } }'La respuesta es 201 Created con el emisor y su certificado, con el encabezado Location del emisor. El emisor ya tiene el establecimiento 001 en su dirección matriz y el punto de emisión 001. El certificado sirve para pruebas y producción (allModes: true) y empieza en processing, como cualquier certificado: léelo bajo el emisor hasta que esté accepted.
{ "issuer": { "id": "01a0fd6a-d098-76ca-b492-1bcb6505a7bd", "ruc": "1790000000001", "legalName": "TOSTADURIA ANDINA S.A.", "tradeName": "Café Andino", "headOfficeAddress": "Av. Amazonas N36-152 y Naciones Unidas, Quito", "taxProfile": { "keepsAccounting": true, "specialTaxpayerNumber": null, "withholdingAgentResolution": "6498", "rimpeRegime": null, "largeTaxpayerResolution": null }, "branding": { "brandColor": null }, "sendEmailByDefault": true, "createdAt": "2026-10-02T16:22:05.000Z", "updatedAt": "2026-10-02T16:22:05.000Z" }, "certificate": { "id": "01a0fd6e-f718-7c9c-b50c-fafb236eb1a6", "issuerId": "01a0fd6a-d098-76ca-b492-1bcb6505a7bd", "environment": "test", "allModes": true, "status": "processing", "usable": false, "subject": null, "issuedBy": null, "serialNumber": null, "validFrom": null, "validUntil": null, "sha256Fingerprint": null, "ruc": null, "revocation": null, "rejection": null, "createdAt": "2026-10-02T16:22:05.000Z", "updatedAt": "2026-10-02T16:22:05.000Z" }}| Error | Cuándo |
|---|---|
409 issuer_onboarding_not_ready |
El alta todavía está en verifying. |
409 issuer_onboarding_rejected |
El certificado fue rechazado. |
409 issuer_onboarding_completed |
El alta ya se completó. |
409 issuer_onboarding_expired |
Pasaron 6 días sin completarla. |
409 issuer_already_exists |
Otra solicitud creó mientras tanto un emisor con este RUC. El alta sigue ready: completarla de nuevo renueva ese emisor (consulta Renovación). |
422 validation_failed |
Falta un campo de un emisor nuevo, o el ruc es obligatorio o no coincide con el certificado (ruc_mismatch en errors). |
RUC de una persona natural
Sección titulada «RUC de una persona natural»El certificado de una persona natural suele traer su cédula, no un RUC. Flashpi propone entonces la cédula seguida de 001 (identification.rucSource: "cedula", rucNeedsConfirmation: true), y al completar debes enviar el ruc: el propuesto, u otro cuyos 10 primeros dígitos sean la cédula. Otro RUC recibe 422 con ruc_mismatch en el campo ruc. Para un certificado con la cédula 1700000001:
{ "ruc": "1700000001001", "legalName": "PEREZ LOPEZ JUAN CARLOS", "headOfficeAddress": "Av. Naciones Unidas E7-10, Quito", "taxProfile": { "keepsAccounting": false, "rimpeRegime": "entrepreneur" }}Cuando el RUC viene del propio certificado (rucSource: "certificate"), ruc se puede omitir; si lo envías, debe ser ese RUC.
Certificado sin RUC
Sección titulada «Certificado sin RUC»Algunos certificados no traen un RUC ni una cédula que Flashpi pueda leer. El alta lista tiene entonces proposedRuc: null, rucNeedsConfirmation: true y sri: null, porque no había un RUC que consultar al SRI, y prefill solo trae lo que se lee del certificado. Al completar debes enviar el ruc, de 13 dígitos terminados en 001 (si falta, 422 con el ruc obligatorio). Flashpi no puede compararlo con el certificado, así que asegúrate de que sea el RUC del titular. Si tu cuenta ya tiene un emisor con ese RUC, completar renueva su certificado y basta con enviar el ruc; si no, envía también los campos de un emisor nuevo.
Renovación
Sección titulada «Renovación»Si tu cuenta ya tiene un emisor con el RUC del certificado, el alta trae existingIssuer y completarla renueva su certificado: no se crea otro emisor, y el cuerpo puede ser {}. El perfil del emisor no cambia; actualízalo con PATCH /v1/issuers/{issuerId} si hace falta. El certificado nuevo sirve para pruebas y producción y toma el relevo en cuanto se acepta (consulta Qué certificado firma).
Datos del SRI
Sección titulada «Datos del SRI»Hoy Flashpi no consulta el registro público de RUC del SRI: sri.status es disabled y prefill solo trae el RUC y la razón social que se leen del certificado. La información tributaria es tu responsabilidad: revisa y completa cada valor antes de completar el alta.
Cuando la consulta se active, Flashpi la hará una sola vez, después de verificar el certificado, con el RUC propuesto, y prefill tomará del SRI la razón social, el nombre comercial, la dirección matriz y el perfil tributario. sri traerá entonces lo que respondió el SRI:
{ "sri": { "status": "found", "fetchedAt": "2026-10-02T16:20:40.000Z", "profile": { "legalName": "TOSTADURIA ANDINA S.A.", "tradeName": "CAFE ANDINO", "taxpayerStatus": "ACTIVO", "keepsAccounting": true, "specialTaxpayer": false, "withholdingAgent": true, "rimpeRegime": "general", "headOfficeAddress": "PICHINCHA / QUITO / IÑAQUITO / AV. AMAZONAS N36-152" }, "warnings": [] }}sri.statusesfound,not_found(el SRI no tiene ese RUC: revisa que sea correcto),unavailable(el SRI no respondió) odisabled(no se consultó).sriesnullcuando el certificado no dio un RUC que consultar (consulta Certificado sin RUC). Cuando no hay perfil,prefillsolo trae lo que se lee del certificado y completas el resto.sri.warningsavisa cuando el RUC no estáACTIVO(inactive), cuando el SRI marca al contribuyente como fantasma (ghost) o por transacciones inexistentes (nonexistent_transactions), o cuando su matriz figura cerrada (head_office_closed). Son solo avisos: nunca impiden completar el alta.profile.rimpeRegimeesentrepreneur,popular_business,general(fuera del RIMPE) ounknown(no se pudo interpretar: elige tú el régimen).generalse envía al completar comorimpeRegime: null, y el SRI solo dice si el contribuyente es contribuyente especial o agente de retención: los números de resolución los escribes tú.
Crear un emisor
Sección titulada «Crear un emisor»También puedes crear un emisor con JSON, sin subir su certificado: sigue funcionando igual, y luego subes el certificado por separado (consulta Certificados). La consola ya no ofrece esta forma.
curl https://api.flashpi.com.ec/v1/issuers \ -H "Authorization: Bearer $FLASHPI_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "ruc": "1790000000001", "legalName": "Tostaduría Andina S.A.", "tradeName": "Café Andino", "headOfficeAddress": "Av. Amazonas N36-152 y Naciones Unidas, Quito", "taxProfile": { "keepsAccounting": true, "withholdingAgentResolution": "6498" }, "branding": { "brandColor": "#5B3A29" }, "sendEmailByDefault": true }'La respuesta es 201 Created con el emisor:
{ "id": "01a0fd6a-d098-76ca-b492-1bcb6505a7bd", "ruc": "1790000000001", "legalName": "Tostaduría Andina S.A.", "tradeName": "Café Andino", "headOfficeAddress": "Av. Amazonas N36-152 y Naciones Unidas, Quito", "taxProfile": { "keepsAccounting": true, "specialTaxpayerNumber": null, "withholdingAgentResolution": "6498", "rimpeRegime": null, "largeTaxpayerResolution": null }, "branding": { "brandColor": "#5b3a29" }, "sendEmailByDefault": true, "createdAt": "2026-10-02T16:20:31.000Z", "updatedAt": "2026-10-02T16:20:31.000Z"}| Campo | Notas |
|---|---|
ruc |
13 dígitos terminados en 001. Solo se valida el formato: los RUC más nuevos no cumplen el antiguo dígito verificador módulo 11, así que Flashpi nunca lo verifica. No puede cambiar después, y una cuenta no puede registrar el mismo RUC dos veces (409 issuer_already_exists; con el alta desde el certificado, el mismo RUC renueva el emisor). |
legalName, tradeName |
La razón social tal como consta en el RUC, y el nombre comercial opcional. El correo al comprador muestra el nombre comercial, o la razón social, como remitente. |
headOfficeAddress |
La dirección matriz. |
taxProfile |
Consulta Perfil tributario. |
branding.brandColor |
El color de marca del RIDE y del correo al comprador, #RRGGBB (se devuelve en minúsculas). |
sendEmailByDefault |
Si los comprobantes autorizados se envían por correo al comprador cuando la solicitud no lo indica (options.sendEmail). true por defecto. Consulta RIDE y correo. |
Perfil tributario
Sección titulada «Perfil tributario»El perfil tributario se configura una sola vez, en el emisor. Flashpi escribe las etiquetas y leyendas que correspondan en cada comprobante, así que las solicitudes nunca las repiten.
| Campo | Lo que Flashpi agrega a los comprobantes |
|---|---|
keepsAccounting (obligatorio) |
Si el contribuyente está obligado a llevar contabilidad. |
specialTaxpayerNumber |
El número de resolución de contribuyente especial, de 3 a 13 letras o dígitos. Los comprobantes de retención aceptan máximo 5 caracteres (incompatible_issuer_profile si no). |
withholdingAgentResolution |
El número de resolución de agente de retención, solo dígitos. |
rimpeRegime |
entrepreneur imprime CONTRIBUYENTE RÉGIMEN RIMPE y popular_business imprime CONTRIBUYENTE NEGOCIO POPULAR - RÉGIMEN RIMPE. null fuera del RIMPE. |
largeTaxpayerResolution |
La resolución de gran contribuyente, impresa como el campo adicional Gran Contribuyente. |
Flashpi también agrega a cada comprobante el campo adicional RUC Proveedor: el RUC del proveedor registrado de facturación electrónica, Signia Digital S.A. (0993411372001). Un comprobante admite máximo 15 campos adicionales, así que estas leyendas ocupan uno o dos, y sus nombres están reservados en tu additionalInfo (reserved_name).
Establecimientos y puntos de emisión
Sección titulada «Establecimientos y puntos de emisión»curl https://api.flashpi.com.ec/v1/issuers/01a0fd6a-d098-76ca-b492-1bcb6505a7bd/establishments \ -H "Authorization: Bearer $FLASHPI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "code": "001", "address": "Av. Amazonas N34-12, Quito" }'curl https://api.flashpi.com.ec/v1/issuers/01a0fd6a-d098-76ca-b492-1bcb6505a7bd/establishments/01a0fd6b-41e0-7c72-a0ce-848650c4f91d/emission-points \ -H "Authorization: Bearer $FLASHPI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "code": "001" }'- Un establecimiento tiene un
codede tres dígitos, tal como consta en el RUC, y unaaddressque se imprime en sus comprobantes. Solo la dirección puede cambiar después (PATCH). - Un punto de emisión tiene un
codede tres dígitos y nada más que cambiar. - Un código ya usado recibe
409establishment_already_existsoemission_point_already_exists. - Las listas de establecimientos y de puntos de emisión se ordenan por código; la de emisores, del más nuevo al más antiguo. Consulta Paginación.
Los comprobantes indican el establecimiento y el punto de emisión por sus códigos ("establishment": "001"), no por sus ID.
Secuenciales y claves de acceso
Sección titulada «Secuenciales y claves de acceso»Flashpi asigna el siguiente secuencial de forma atómica por emisor, establecimiento, punto de emisión y tipo de comprobante, así que dos solicitudes simultáneas nunca reciben el mismo número, y genera la clave de acceso de 49 dígitos con un código numérico aleatorio. Las facturas y las notas de crédito de un mismo punto de emisión tienen series separadas.
Una solicitud puede enviar su propio sequential (de 1 a 999.999.999), por ejemplo para continuar la numeración del sistema del que migras:
- No debe estar usado por otro comprobante del mismo tipo y serie (
409sequential_already_used). - Si es mayor que el último, los secuenciales automáticos siguientes continúan después de él. Un secuencial libre menor llena un hueco y no mueve el contador.
- Una serie que llegó a 999.999.999 recibe
409sequentials_exhausted. - El emisor demo compartido nunca acepta uno.
Actualizar y eliminar
Sección titulada «Actualizar y eliminar»PATCH /v1/issuers/{issuerId}cambia los campos que envíes;nullborra un campo opcional. El RUC nunca cambia.DELETE /v1/issuers/{issuerId}elimina el emisor con sus establecimientos, puntos de emisión y API keys de ese emisor. Se rechaza con409resource_in_usemientras haya comprobantes o certificados que lo usen, así que un emisor que emitió comprobantes se queda.- Tampoco se puede eliminar un establecimiento o punto de emisión con comprobantes (
409resource_in_use).
Hoy la marca de un emisor es su brandColor, que usan el RIDE y el correo al comprador. Subir un logo del emisor está planificado. La plantilla del RIDE (modern, classic o minimal) se elige por cuenta en la consola; consulta RIDE y correo.