Signing certificates
The SRI only accepts documents signed (XAdES-BES) with the issuer’s electronic signature: a .p12 (PKCS#12) file issued by a certification authority accredited in Ecuador. Flashpi keeps it encrypted, checks it with its certification authority and signs every document of the issuer with it.
The shared demo issuer signs with Flashpi’s own test certificate, so you only need yours to issue with your own RUC.
There are two ways to upload a certificate:
- The onboarding from the certificate (
POST /v1/issuer-onboardings): creates the issuer from its.p12, or renews the certificate of the issuer that already has that RUC. The certificate serves test and live (allModes: true). It is what the console does. See Create an issuer from its certificate and Renew a certificate. - The upload to an issuer (
POST /v1/issuers/{issuerId}/certificates, below): the certificate serves the environment of the key that uploads it.
Upload
Section titled “Upload”Upload the file and its password as multipart/form-data. It needs an account-scoped read_write key.
curl https://api.flashpi.com.ec/v1/issuers/01a0fd6a-d098-76ca-b492-1bcb6505a7bd/certificates \ -H "Authorization: Bearer $FLASHPI_API_KEY" \ -F "file=@signature.p12" \ -F "password=$P12_PASSWORD"file: the.p12file, at most 1 MiB (1,048,576 bytes;413payload_too_largebeyond it).password: its password, at most 1024 bytes.- The key’s environment matters. A certificate uploaded here with a test key signs only test documents; one uploaded with a live key signs only live documents. For one certificate that serves both environments, use the onboarding from the certificate.
The answer is 202 Accepted with the certificate in status processing:
{ "id": "01a0fd6e-f718-7c9c-b50c-fafb236eb1a6", "issuerId": "01a0fd6a-d098-76ca-b492-1bcb6505a7bd", "environment": "test", "allModes": false, "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:25:03.000Z", "updatedAt": "2026-10-02T16:25:03.000Z"}Flashpi encrypts the file and the password as soon as they arrive. The password is never stored in clear and never returned. GET /v1/issuers/{issuerId}/certificates lists an issuer’s certificates (newest first) and GET /v1/issuers/{issuerId}/certificates/{certificateId} reads one.
allModes says whether the certificate serves test and live (uploaded through the onboarding from the certificate). A key reads the certificates of its environment and those of both, and on a certificate of both environments environment is the environment of the key that reads it.
Renew a certificate
Section titled “Renew a certificate”To renew an issuer’s signature with one certificate for both environments, start an onboarding from the certificate with the new .p12. Since your account already has an issuer with that RUC, the ready onboarding carries existingIssuer, and you complete it with an empty body:
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 '{}'The new certificate is added to the issuer (allModes: true, processing) without changing its profile. In the console, Upload certificate on an issuer does the same: you choose no environment and confirm with your authenticator code or your password. When the .p12 belongs to another RUC, the console takes you to New issuer with the same file. Members who write the certificates of some issuers without managing issuers upload one certificate per environment instead.
Verification
Section titled “Verification”An isolated service opens the file and checks the password, that it holds exactly one signing key with its certificate, its validity dates, its chain up to an accredited Ecuadorian certification authority, and its revocation status with that authority. It usually takes a few seconds. Read the certificate again until its status is no longer processing:
accepted: it can sign. The certificate now shows itssubject,issuedBy,serialNumber,validFrom,validUntil,sha256Fingerprint, therucwritten in it (when its authority writes one) and itsrevocationstate. Flashpi raisescertificate.verified, orcertificate.pendingwhen the revocation status could not be checked yet.rejected:rejection.codeandrejection.messagesay why. A rejected upload raises no webhook event today.
rejection.code |
Meaning |
|---|---|
invalid_password |
The password does not open the file. |
invalid_pkcs12 |
The file is not a valid .p12. |
pkcs12_mac_missing |
The file has no password integrity check. Export it again with a password. |
no_signing_certificate |
No private key with a signing certificate in the file. |
ambiguous_signing_certificate |
Several signing certificates in the file. Upload a file with only one. |
certificate_not_yet_valid, certificate_expired |
Outside its validity dates. |
untrusted_certificate_chain |
Not issued by a certification authority accredited in Ecuador. |
certificate_revoked |
Its certification authority revoked it. |
revocation_status_unknown |
Its revocation status could not be determined. |
certificate_unsupported |
A format Flashpi cannot use. |
upload_unreadable, upload_too_large |
The upload could not be read, or is too large. |
Revocation checks
Section titled “Revocation checks”A certificate can be revoked by its authority at any time, for example when its owner reports it lost. Flashpi checks every accepted certificate again: daily while its status is good, hourly while it is pending or blocked. The revocation object shows the result:
revocation.status |
Signs? | What it means |
|---|---|---|
good |
Yes | Verified not revoked. checkedAt and nextCheckAt say when it was and will be checked. |
pending |
Yes, until blockAt |
The authority’s revocation service did not answer, so the status could not be verified. Flashpi keeps trying every hour. |
blocked |
No | Still unverified at blockAt (blockedReason: "revocation_status_unverified"), or its chain is no longer trusted (blockedReason: "untrusted_certificate_chain"). |
revoked |
Never again | Its certification authority revoked it. |
How a certificate moves between them:
- When the status cannot be verified, the certificate becomes
pendingwith ablockAt7 days later (certificate.pending). It keeps signing meanwhile. - Reminders are raised on days 3 and 6, as
certificate.pendingagain. - Verified good before
blockAt: back togood(certificate.verified). - Still unverified at
blockAt:blocked(certificate.blocked). It stops signing atblockAteven if a check runs late. Once a check verifies it good, it is reactivated and signs again (certificate.reactivated). - A good certificate that cannot be verified on a later check goes back to
pending, with a new 7-day window. - If its chain is no longer trusted (the authority or an intermediate certificate changed), it is
blockedat once. Upload a new certificate. - If the authority reports it revoked, it becomes
revoked(certificate.revoked) and never signs again. A revoked certificate is also refused at upload.
What you see as a customer
Section titled “What you see as a customer”- The certificate itself:
usablesays whether it signs right now (accepted, within its validity dates, and not blocked or revoked; a pending certificate is usable until itsblockAt). - The console shows a banner on the issuer’s certificates when one is pending (with the date it stops signing), blocked, revoked, expired or about to expire.
- Webhooks: subscribe to
certificate.pending,certificate.blocked,certificate.revoked,certificate.reactivatedandcertificate.verifiedto alert your team. Theirdatais the certificate. The events of a certificate of both environments are recorded once per environment, so the test endpoints and the live ones both get them. See Webhooks. - Documents: a document issued while the issuer has no usable certificate for its environment is accepted, then ends
failedwithfailure.codecertificate_required,certificate_blocked,certificate_revoked,certificate_expiredorcertificate_not_yet_valid. It uses up its sequential, so issue it again once a certificate signs.
Which certificate signs
Section titled “Which certificate signs”Documents are signed with the newest usable certificate that serves their environment: one uploaded for that environment, or one of both environments (allModes). To renew a signature, upload the new .p12 before the old one expires (Renew a certificate): once accepted, it takes over, and the older one only signs if the newer one stops being usable.
How the certificate is protected
Section titled “How the certificate is protected”- The file and the password are encrypted on arrival with a key managed by AWS KMS, in a dedicated storage area. An upload to an issuer is deleted once checked. The upload of an onboarding from the certificate waits for you to complete the onboarding, which deletes it; one never completed (a rejected or expired one included) is deleted automatically about 7 days after it was uploaded.
- Only the isolated signing service can decrypt the certificate, in memory, to sign your documents. The API that receives your requests cannot read it.
- See Security.