API
The public REST interface for your own integrations.
Base URL
All requests go to https://api.brivio.ro. Responses are JSON, and errors follow one contract: a code, a message and, where relevant, the list of invalid fields.
What is covered
The endpoints cover sales documents, partners, the catalogue and stock. Spaces (/spaces) group the domains, sites and apps of a project and can be managed with an API key; space transfers (/space-transfers) are read-only, because moving a space to another organisation needs a person in the app with a second factor. Accounting operations are not exposed for writing: entries are generated from documents, and a direct write path could produce entries with no source document.
Newsletter subscribers (double opt-in)
POST /v1/marketing/subscribers lets the backend of a public form (a site footer, a landing page) add someone to your organisation's newsletter. Brivio sends the confirmation email, hosts the confirmation page and keeps the consent evidence; the person only becomes a subscriber after they confirm.
The key needs the scope marketing_subscribers:write. It stands alone and is not implied by marketing:write, so a key that lives on a public form's server can add subscribers but cannot send campaigns. The optional Idempotency-Key header is honoured (24 h replay).
Request body:
email— required, up to 320 characters, lowercased by the server.name— optional, up to 200 characters.locale—rooren, defaultro; the language of the confirmation email and pages.source— optional, up to 120 characters; where the form lives, for your own reporting.redirect_url— optionalhttpsURL; after a successful confirmation the person is sent there (303) with?status=confirmed.consent— required, the evidence GDPR art. 7(1) asks the controller to be able to show:text_version— required, 1–64 characters, the version of the consent wording the person saw;text— optional, up to 2000 characters, stored only as a SHA-256 hash;ip— optional, the end user's IP (not your server's), stored only as a salted hash;user_agent— optional, truncated to 300 characters.
Brivio keeps hashes rather than the raw IP and wording: enough to prove later which text a given request agreed to, without storing more personal data than the proof needs.
Responses use the usual { data, error } envelope with a MarketingSubscriber object:
201— a new subscriber was created with statuspendingand a confirmation email was sent.200— the address is already known for your organisation. The call is idempotent per address: the current state is returned unchanged, or the confirmation is re-sent if the subscriber is stillpendingand the cooldown has passed, or a previouslyunsubscribedaddress goes back topending.confirmation_senttells you whether this call sent an email.422VALIDATION_ERROR,401,403SCOPE_REQUIRED,429RATE_LIMITED.
The status moves pending → subscribed → unsubscribed. The confirmation link opens a page with a button: opening the link (GET) never changes anything, because mail security scanners follow every link; pressing the button (POST) confirms. The link is signed, single-use and valid for 24 hours. Every subscriber also gets unsubscribe_url, an RFC 8058 one-click unsubscribe link that works both from the mail client's unsubscribe button and from a browser.
Limits: 600 requests per hour per organisation, and at most one confirmation email per address every 10 minutes.
curl https://api.brivio.ro/v1/marketing/subscribers \
-H "Authorization: Bearer $BRIVIO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2e4a-newsletter-footer" \
-d '{
"email": "ana@example.ro",
"name": "Ana",
"locale": "ro",
"source": "example.ro/footer",
"redirect_url": "https://example.ro/newsletter/confirmed",
"consent": { "text_version": "2026-10-05", "text": "I agree to receive the monthly newsletter.", "ip": "203.0.113.7" }
}'const subscriber = await brivio.marketing.createSubscriber({
email: "ana@example.ro",
name: "Ana",
locale: "ro",
source: "example.ro/footer",
consent: { text_version: "2026-10-05", text: consentText, ip: request.ip },
});
// subscriber.status === "pending" until Ana confirms$subscriber = $brivio->createMarketingSubscriber([
'email' => 'ana@example.ro',
'locale' => 'ro',
'source' => 'example.ro/footer',
'consent' => ['text_version' => '2026-10-05', 'ip' => $_SERVER['REMOTE_ADDR']],
]);Full reference
Every operation, with its request shape, responses and code samples, is generated from the OpenAPI document at /reference. The same document drives the TypeScript, PHP, Python, Go, Java and .NET SDKs, so what you read there is what the SDK calls.