Fac-360
Organizations

List the client companies of the calling organization

The read that makes this surface usable: every company, with the nine capability flags that decide what it may do and the state of the certificate that decides whether it may sign at all. Keyset paginated on the RUC, which is unique platform-wide, so a page cannot skip or repeat a company because another was registered mid-scan. INACTIVE companies are not listed. Requires organizations:read.

GET
/api/v2/organizations/companies

The read that makes this surface usable: every company, with the nine capability flags that decide what it may do and the state of the certificate that decides whether it may sign at all. Keyset paginated on the RUC, which is unique platform-wide, so a page cannot skip or repeat a company because another was registered mid-scan. INACTIVE companies are not listed. Requires organizations:read.

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

Query Parameters

limit?integer
Range1 <= value <= 200
Default50
cursor?string

The RUC the previous page ended on; this page starts strictly after it.

Match^[0-9]{11}$

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/api/v2/organizations/companies" \  -H "Authorization: Bearer apf_v2_tu_credencial"
{  "schemaVersion": "2.0",  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",  "organizationId": "7bc05553-4b68-44e8-b7bc-37be63c6d9e9",  "companies": [    {      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",      "ruc": "string",      "legalName": "string",      "status": "ACTIVE",      "environment": "BETA",      "createdAt": "2019-08-24T14:15:22Z",      "capabilities": [        {          "capability": "string",          "enabled": true        }      ],      "certificate": {        "readyToSign": true,        "active": {          "configurationId": "254ffdcc-3725-465c-b0a0-22afb2bec267",          "version": 1,          "status": "DRAFT",          "createdAt": "2019-08-24T14:15:22Z",          "activatedAt": "2019-08-24T14:15:22Z",          "retiredAt": "2019-08-24T14:15:22Z",          "serialNumber": "string",          "issuer": "string",          "subjectRuc": "string",          "notBefore": "2019-08-24T14:15:22Z",          "notAfter": "2019-08-24T14:15:22Z",          "revokedAt": "2019-08-24T14:15:22Z",          "activation": {            "activationId": "a606ed3b-704a-4227-aa5c-f71d4aee9a1f",            "status": "PENDING",            "responseCode": "string",            "responseMessage": "string",            "failureCode": "string",            "startedAt": "2019-08-24T14:15:22Z",            "finishedAt": "2019-08-24T14:15:22Z"          }        },        "latest": {          "configurationId": "254ffdcc-3725-465c-b0a0-22afb2bec267",          "version": 1,          "status": "DRAFT",          "createdAt": "2019-08-24T14:15:22Z",          "activatedAt": "2019-08-24T14:15:22Z",          "retiredAt": "2019-08-24T14:15:22Z",          "serialNumber": "string",          "issuer": "string",          "subjectRuc": "string",          "notBefore": "2019-08-24T14:15:22Z",          "notAfter": "2019-08-24T14:15:22Z",          "revokedAt": "2019-08-24T14:15:22Z",          "activation": {            "activationId": "a606ed3b-704a-4227-aa5c-f71d4aee9a1f",            "status": "PENDING",            "responseCode": "string",            "responseMessage": "string",            "failureCode": "string",            "startedAt": "2019-08-24T14:15:22Z",            "finishedAt": "2019-08-24T14:15:22Z"          }        }      },      "certificatePath": "string",      "credentialsPath": "string"    }  ],  "page": {    "limit": 1,    "nextCursor": "string"  }}

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.

Register a client company under the calling organization POST POST

Creates the fiscal entity a platform will issue for. Requires an ORGANIZATION credential (apf_org_v2_...) carrying companies:manage; a company credential is refused by the token prefix before any lookup happens. The company is created ACTIVE but can sign nothing: it has no certificate, and since migration 000052 the only route to an ACTIVE certificate is a comprobante SUNAT accepted. Every call writes an ops.audit_events row naming the organization, the credential and the RUC, in the same transaction as the company.