Skip to main content

Authentication

Every API Connect request is authenticated with an API key in the Authorization header using the Bearer scheme.

Authorization: Bearer odt_f57b5eabebb5ee8698d54c5c9427a991f6254150e819d04b2f56a490

There is no other authentication scheme. We don't use OAuth, we don't use sessions, and there is no automatic token rotation. An API key is long-lived until you deactivate it.

Obtaining an API key

API keys are issued by Ocote directly against a company configured in the platform. The flow is:

  1. You (or your customer) already has the company registered in Ocote DTE, with the MH signer loaded and at least one branch/POS active.
  2. Ocote generates the API key from the admin panel and hands it to you.
  3. You store it in your secret manager.

The key is associated with the company and does not expire by default, but can be deactivated at any time from the Ocote panel (the event is logged and any subsequent request returns 401).

Token format

API keys follow the format:

odt_[56 hexadecimal characters]

The odt_ prefix (Ocote DTE) is fixed and helps you spot them visually if you see them in logs or environment variables. A typical key:

odt_f57b5eabebb5ee8698d54c5c9427a991f6254150e819d04b2f56a490

How to send it

Standard header for every read/write request:

POST /api/connect/invoice HTTP/1.1
Host: ocote.io
Authorization: Bearer odt_xxx
Content-Type: application/json

Exception: file download endpoint.

The GET /file/{id} endpoint accepts the key as a query parameter instead of a header, because it is often used directly from the browser (open a ticket, share a JSON link):

GET /api/connect/file/{document_id}?type=ticket&key=odt_xxx

Everything else — issuance, query, invalidation — always uses the Authorization header.

Examples

curl
curl https://ocote.io/api/connect/status/SALE-2026-0042 \
-H "Authorization: Bearer odt_f57b5eabebb5ee8698d54c5c9427a991f6254150e819d04b2f56a490"
Node.js (axios)
import axios from 'axios';

const ocote = axios.create({
baseURL: 'https://ocote.io/api/connect',
headers: {
'Authorization': `Bearer ${process.env.OCOTE_API_KEY}`,
'Content-Type': 'application/json',
},
});

const { data } = await ocote.get('/status/SALE-2026-0042');
console.log(data);
Python (requests)
import os, requests

headers = {
"Authorization": f"Bearer {os.environ['OCOTE_API_KEY']}",
"Content-Type": "application/json",
}

r = requests.get(
"https://ocote.io/api/connect/status/SALE-2026-0042",
headers=headers,
)
r.raise_for_status()
print(r.json())
PHP (Guzzle)
use GuzzleHttp\Client;

$client = new Client([
'base_uri' => 'https://ocote.io/api/connect/',
'headers' => [
'Authorization' => 'Bearer ' . getenv('OCOTE_API_KEY'),
'Content-Type' => 'application/json',
],
]);

$response = $client->get('status/SALE-2026-0042');
echo $response->getBody();

Authentication error responses

HTTPMessageCause
401API key requeridaMissing Authorization header or doesn't start with Bearer .
401API key invalidaKey does not exist or was deactivated.
401Empresa inactivaCompany bound to the key is disabled.

401 responses do not count against rate limit. 400/500 responses don't count against the hourly limit either, but do count against the minute limit (see Rate limits).

Rotation and security

  • Treat the key like a password. Don't expose it in the frontend, don't commit it to repos, don't send it over unencrypted channels.
  • If compromised, request a new key from Ocote and deactivate the old one. Any subsequent request with the old key will return 401. Your external_refs remain yours: issuances you made before stay queryable with the new key as long as they belong to the same company.
  • One key per environment is recommended. If you have stage and production, use two different keys — typically one on a test-environment company and another on a production-environment company.
Don't embed the key in the browser

The API Connect is meant to be consumed from a backend. If your frontend needs to display DTE info, the correct pattern is for your backend to query the API with the key and expose its own endpoint to the frontend.