Companies
Link digital certificate
Uploads the company A1 digital certificate (.pfx / .p12) and its password; accepts JSON + Base64 or multipart.
/openapi/v1/empresas/{empresaId}/certificadoDigitalRequires the token, timestamp and sign signature headers, see Authentication.
The same path accepts two request shapes, selected by Content-Type: use JSON + Base64 (this page) when you only hold the certificate bytes, for example read from your own storage, which avoids assembling multipart and its signing caveats; use multipart (section below) when you hold the certificate as a file. Validation and outcome are identical for both shapes. A successful upload replaces the company's previous certificate.
Parameters
Headers
Content-Typestringrequiredapplication/jsonfor the JSON + Base64 shape;multipart/form-datafor the multipart shape.
Path parameters
empresaIdstringrequiredIdentifier returned by Register company.
Example:1934811222334455
Request body
senhastringrequiredCertificate password.
Example:certpass123arquivoBase64stringrequiredBase64 of the .pfx / .p12 file content; line breaks and a
data:...;base64,prefix are tolerated; at most 1MB after decoding. Invalid Base64 or oversize returns10003035.Example:MIIKXQIBAzCCCicGCSqGSIb3DQEHAaCCChgEggoU...
Responses
Certificate validated and linked; no response body. The company's previous certificate is replaced.
No response body
Errors
| Code | HTTP | |
|---|---|---|
| 10003000 | 404 |
|
| 10003035 | 400 | Invalid Base64 or file above 1MB after decoding (JSON shape only). |
| CER0005 | 400 | Certificate password mismatch. Check the password. |
| 10003010 | 400 | Certificate CNPJ does not match the company. Use the correct certificate. |
| 10003011 | 400 | Certificate expired. Use a valid certificate. |
| 10003012 | 400 | Certificate identical to the one currently active for the company. |
Signing the JSON shape
For the JSON shape the body is part of the signature (raw body with CR/LF removed, same as every other JSON endpoint). Produce standard Base64 without line breaks so the signed body and the sent body cannot drift apart.
APP_SECRET="sk_live_9f8e7d6c5b4a"P="/openapi/v1/empresas/1934811222334455/certificadoDigital"TS=$(date +%s)BODY=$(printf '{"senha":"certpass123","arquivoBase64":"%s"}' "$(base64 -w0 uploaded-cert.pfx)")SIGN=$(printf '%s' "${APP_SECRET}${P}${BODY}${TS}" | md5sum | cut -d' ' -f1)curl -X POST "https://api.v2.tffiscal.com${P}" \-H "token: ${APP_SECRET}" -H "timestamp: ${TS}" -H "sign: ${SIGN}" \-H "Content-Type: application/json" --data-binary "${BODY}"
Alternative shape: multipart file upload
Send Content-Type: multipart/form-data with the form fields below.
| Form field | Type | Required | Description |
|---|---|---|---|
senha | text | yes | Certificate password |
arquivo | file | yes | A1 digital certificate file (.pfx / .p12), up to 1MB |
Signing note: for multipart requests the body is the empty string (sign = MD5(token + path + timestamp)).
APP_SECRET="sk_live_9f8e7d6c5b4a"P="/openapi/v1/empresas/1934811222334455/certificadoDigital"TS=$(date +%s)SIGN=$(printf '%s' "${APP_SECRET}${P}${TS}" | md5sum | cut -d' ' -f1)curl -X POST "https://api.v2.tffiscal.com${P}" \-H "token: ${APP_SECRET}" -H "timestamp: ${TS}" -H "sign: ${SIGN}" \-F "senha=certpass123" -F "arquivo=@uploaded-cert.pfx"
Validation and outcome (both shapes)
Platform checks: Base64 validity (JSON shape only, 10003035), password matches (CER0005 otherwise), certificate not expired (10003011), certificate CNPJ matches the company (10003010), not identical to the currently active certificate (10003012). Success is HTTP 200 with no body. A successful upload replaces the company's previous certificate. The certificate content is stored encrypted on the platform side; no endpoint ever returns the certificate content or its password.
The company only becomes issuable once, in addition to the certificate, the operations approval is complete; see the lifecycle in Companies.
