Fac-360
Certificates

Read the verdict of this version's activation probe

The poll target the 202 names. Reports the probe's own status, the certificate's status beside it — they are two different questions, and a probe that ended REJECTED leaves a version that is still DRAFT — and the SUNAT verdict verbatim, because a responseCode is what tells an operator which certificate to replace where 'activation failed' tells them nothing. Requires no Idempotency-Key: it is a read. A version that never requested activation answers 404 CERTIFICATE_ACTIVATION_NOT_FOUND, which is not the same as an unknown id: the version exists and simply has no attempt against it.

GET
/api/v2/certificates/{id}/activation

The poll target the 202 names. Reports the probe's own status, the certificate's status beside it — they are two different questions, and a probe that ended REJECTED leaves a version that is still DRAFT — and the SUNAT verdict verbatim, because a responseCode is what tells an operator which certificate to replace where 'activation failed' tells them nothing. Requires no Idempotency-Key: it is a read. A version that never requested activation answers 404 CERTIFICATE_ACTIVATION_NOT_FOUND, which is not the same as an unknown id: the version exists and simply has no attempt against it.

Authorization

bearerAuth
AuthorizationBearer <token>

Tenant-bound, scoped and expiring Apifact credential. Migrated legacy credentials are accepted only on deprecated v1 writes and tenant-scoped v2 read, poll and download routes. Each operation names the single scope it requires in x-required-scope; the scope array of the security requirement itself is empty because OpenAPI 3.0 requires it to be for a non-oauth2 scheme.

In: header

Path Parameters

id*string
Formatuuid

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/api/v2/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08/activation" \  -H "Authorization: Bearer apf_v2_tu_credencial"
{  "schemaVersion": "2.0",  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",  "activationId": "a606ed3b-704a-4227-aa5c-f71d4aee9a1f",  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "version": 1,  "environment": "BETA",  "status": "PENDING",  "certificateStatus": "DRAFT",  "probe": {    "documentType": "01",    "series": "F000",    "number": "string",    "responseCode": "string",    "responseMessage": "string",    "failureCode": "string",    "probedAt": "2019-08-24T14:15:22Z"  },  "createdAt": "2019-08-24T14:15:22Z",  "finishedAt": "2019-08-24T14:15:22Z"}

Enrol a signing certificate and its SOL credentials as a DRAFT version POST POST

Uploads the four secrets a Peruvian issuer needs: the PKCS#12 certificate (base64), its password, and the SOL user and password of the SUNAT secondary user. All four together, because a certificate signs the XML and the SOL credentials authenticate sendBill: one without the other cannot submit anything. The upload is validated BEFORE it is stored — the PFX must open with the supplied password, the certificate subject RUC must be this company's RUC, the validity window must cover now, and the declared environment must be the one the company is enrolled for — and only then sealed. The new version is created in DRAFT and signs NOTHING until POST /api/v2/certificates/{id}/activation. The certificate and the passwords are never stored in plaintext, never logged and never returned; only the sealed envelopes reach storage, and only their digests reach the database. A repeated Idempotency-Key answers 200 with replay=true and the version the first call produced, without re-sealing anything; the same key with a different certificate is a 409.

Prove a DRAFT version against SUNAT and activate it only if SUNAT accepts POST POST

Requests activation of the named DRAFT. It does NOT promote it in the request, in either environment: a version becomes ACTIVE only when SUNAT has accepted a comprobante signed with it. What differs is WHICH comprobante, and the mechanism field in the 202 says which of the two you got. BETA — mechanism PROBE. This API signs a real factura with the DRAFT certificate and sends it to SUNAT beta; the version becomes ACTIVE only if SUNAT accepts it. A certificate that cannot issue is therefore never activated, which is the whole point — the behaviour before this promoted on request, and the first document the tenant tried to issue was the one that discovered the key was unusable. The probe issues documentType 01 on the reserved series F000 with number equal to the enrolment version, so it is unique per version and never reused. It writes no row in the document collections: it is not a comprobante of the tenant's, it is not listed, it has no artifacts and it consumes no quota. Because a SUNAT round trip can take up to the dispatch timeout, this answers 202 with an operationId and a statusPath rather than blocking; poll GET /api/v2/certificates/{id}/activation for the verdict. PRODUCTION — mechanism FIRST_ISSUE, and it is a different shape because the probe cannot exist here. A probe in production is a REAL comprobante: it enters the taxpayer's registro de ventas and is withdrawn only by an accepted comunicación de baja. Inventing a sale to prove a key is not this platform's decision to make, and refusing to activate at all — which is what this route did until now — left a taxpayer with a certificate that could never sign and a company that could never send. So nothing is sent. The version is ARMED: its status becomes PENDING_FIRST_ISSUE, it signs your documents from this response onwards, and the FIRST comprobante you issue that SUNAT accepts or observes promotes it to ACTIVE in the same transaction that records that CDR — along with the company capabilities that follow a first activation. Nothing is emitted that you were not going to emit anyway. If SUNAT then refuses that first comprobante because of the CERTIFICATE OR THE SOL CREDENTIALS — a wrong password, an unknown or inactive SOL user, no CPE profile, a file whose RUC is not the user's — the version is RETIRED and you enrol another. If SUNAT refuses it for anything else, including every CDR rejection about the CONTENT of the document, the version STAYS ARMED and your next comprobante tries again with the same key. A rejection is a statement about the document, not about the certificate, and retiring a good key over one is worse than leaving it pending. Arming is refused with 409 CERTIFICATE_FIRST_ISSUE_OCCUPIED when the company already has a PRODUCTION version that is ACTIVE or already armed; at most one version per company and environment can be either. That means this mechanism does not renew: it is for a company with no signing certificate at all. Everything decidable without SUNAT is still refused synchronously and by name in both environments: not a DRAFT, revoked, expired, already probed, another attempt in flight. Idempotency-Key is required: a retry after a lost response adopts what was already recorded with replay=true, and re-sending the same key also repairs an attempt whose row committed but whose probe never started.