What's new

2026-08: free trial, in-place reconnect, and a wider CLI

data.status on account events now always means one thing: the account's lifecycle status. On an account_status delivery, data.status is the state the account is in once the event has been applied, one of active, connecting, reconnect_needed, restricted, disconnected. It is the same vocabulary GET /v1/accounts/{account_id} returns.

This is a repair, not a breaking change, and it is worth being precise about why. The field was already sending two different values for the same event depending on which internal path noticed the change: a session expiry detected by the real-time push sent "account.reconnect_needed", while the same event detected by the daily reconciliation sent "reconnect_needed", and nothing in the delivery said which. No handler could have been reliably depending on either form; one branching on the event-name form was already failing silently about half the time. Every producer now sends the lifecycle status, so the value is stable per event for the first time.

If you were branching on data.status, switch to the top-level event field (or its guaranteed copy at data.event), which has always carried the canonical event name and is unchanged. The account status events reference carries the complete event to status mapping, and its examples now match what the server sends; several of them previously showed a value no producer ever sent.

account.restricted is subscribable. LinkedIn restricting an account is now an event you can receive. It was previously emitted by the platform but missing from the catalogue, so POST /v1/webhooks rejected it and no subscription could ever match it; a workspace subscribed to every other account_status event was told nothing when an account was restricted. It is in the default set, so an account_status webhook created without an explicit events array now receives it, and no existing subscription changes: events is fixed when the webhook is created. It carries availability: "not_realtime", because a daily reconciliation is what normally notices the restriction (allow up to 24 hours for that path); a connect that observes the account already restricted can also deliver this event immediately, and reading the account directly with GET /v1/accounts/{account_id} always reports the state sooner than either. Treat it as a stop signal and pause outreach for that account.

Free trial. New workspaces start on a trial seat. Five trial-specific error codes are now part of the taxonomy: TRIAL_EXPIRED (402), TRIAL_SEAT_LIMIT (409), TRIAL_ACTIVE_SEAT_LIMIT (409), TRIAL_IDENTITY_ALREADY_USED (409), and TRIAL_IDENTITY_UNRESOLVED (422). A trial seat does not raise your rate-limit quota; see Rate limits.

In-place reconnect. POST /v1/auth/intent re-authenticates an existing account when you pass account_id in the body, keeping the id, the seat, and the webhook subscriptions. The CLI exposes it as curviate account link --account-id acc_.... Disconnecting and re-linking is no longer the way to refresh a stale session.

Webhook delivery health now tells you the truth. Three corrections to GET /v1/webhooks, worth reading if you monitor webhook health programmatically.

  • delivery_success_rate_7d is null, not 100, when a webhook has made no delivery attempts in the last 7 days. It previously reported a perfect score for a webhook that had never delivered anything, which read as healthier than one that had failed every attempt. It is documented as a percentage (0-100), which is the scale it has always returned; the reference previously described it as a 0-1 fraction. The values on the wire are unchanged apart from the new null.
  • last_delivery_at now carries the most recent delivery attempt, whether it succeeded or failed. It previously carried only the last successful one, so a webhook that had failed every attempt was indistinguishable from one that had never been used. Together the two fields now separate the cases: null and null means never used; 0 with a timestamp means failing. Note that the rate is windowed to 7 days and the timestamp is not, so a webhook whose only attempts are older than a week returns a null rate alongside a non-null last_delivery_at.
  • last_delivery_at is also now RFC 3339, matching created_at in the same object. It previously emitted the raw database format (2026-07-27 16:11:15.685623+00: a space separator, no Z, an hour-only offset), which strict parsers such as Go's time.RFC3339 and Java's OffsetDateTime.parse reject. JavaScript's new Date() accepts both forms, so lenient clients see no change; anyone strict could not have been parsing this field successfully before. It lands in the same release as the meaning change above, so re-read the field once and you are done.
  • secret_prefix from POST /v1/webhooks is the first 8 characters of the secret, with no trailing .... It now matches what GET /v1/webhooks/{id} and GET /v1/webhooks return for the same webhook, so a stored create value compares equal to a later read.

Deleting a webhook stops delivery immediately. Retries that were already queued for a deleted or disabled webhook are dropped rather than delivered. Previously a deletion left queued attempts to fire for hours afterwards.

Latest clients. @curviate/sdk 0.18.1 and @curviate/cli 0.19.0.

Notable client changes since 0.14.0:

  • CLI inbox search (free-text inbox search) and sales-nav search "<url>" for a pasted Sales Navigator URL.
  • CLI job command family: draft, price, publish, close, and review applicants.
  • CLI profile update, profile follow, profile unfollow, profile following; profile connections renamed profile relations.
  • CLI company-page surface: company managed, company chats, company messages, company search-chats, company reply.
  • CLI inbox sync and inbox sync-chat removed; message history syncs implicitly.
  • CLI message inmail --surface removed; every InMail sends from the account's own credits.

2026-07: webhooks, bigger event catalogue, honest delivery labels

That release took the webhook event catalogue to 27 events, 24 of them subscribable across the messaging, user, and account_status sources, each annotated with a delivery-availability label so you know how an event is delivered before you build on it. See the entry above for the current size.

Delivery availability labels. GET /v1/webhooks/events returns an availability field on the events that are not delivered in real time: not_realtime (delivered on a poll delay of hours, applying to connection.accepted and connection.new) and no_longer_realtime (not delivered on the current platform). account.restricted joined the not_realtime set later; see the entry above. Most events omit the field, which means real-time; the three account.initial_sync.* events carry realtime explicitly. Do not build latency-sensitive logic on anything that is not real-time.

Six new opt-in events. These are additive and never auto-subscribed. Name them explicitly in the events array to receive them:

  • chat.updated, chat.deleted: chat-container state changes (messaging).
  • connection.new: any new relation on the account, not only invitations you sent (user).
  • account.initial_sync.running, account.initial_sync.completed, account.initial_sync.failed: these bracket the initial history backfill for a newly connected account (account_status).

Four account events are no longer delivered. account.synced, account.creation_failed, account.connecting, and account.permission_revoked now carry availability: "no_longer_realtime". For account.creation_failed and account.permission_revoked, detect the state with an on-demand account read (GET /v1/accounts/{account_id}); account.synced and account.connecting have no equivalent read-path signal. Note that create still accepts all four and returns 201; you simply never receive a delivery.

Retrieve a single webhook. GET /v1/webhooks/{id} returns one webhook you own. The plaintext secret is never present on a read, only its 8-character prefix. For health, last_delivery_at, and delivery_success_rate_7d, use GET /v1/webhooks.

The SDK and CLI shipped these changes in 0.14.0.


2026-05: initial release

Curviate API v1 is live. Resource groups: Accounts, Messaging, Profiles, Invites, Search, Posts, Sales Navigator, Recruiter, Webhooks. Core tier available; Sales Navigator and Recruiter add-ons in early access.


Subscribe to release notes at hello@curviate.com.

Next steps

COMPANY · LEGAL

Privacy Policy

Redmer Holding GmbHLast updated August 4, 2026

Who we are

Curviate is operated by Redmer Holding GmbH ("Curviate", "we", "us"), a German GmbH registered at Amtsgericht Bonn, HRB 29957, registered address Hostertstraße 16, 53332 Bornheim, Germany. Full company details are on our Imprint. We haven't appointed a statutory Data Protection Officer, since our processing doesn't reach the scale or sensitivity that requires one. Privacy questions go to privacy@curviate.com.

The two roles we play

When you create an account and use Curviate, we process your own data (identity, billing, API keys, connector authorizations). For that data, we are the controller.

When you use Curviate to act on your own connected LinkedIn account, viewing profiles, sending messages, managing engagement, that content and those contacts belong to that account and its people. You are the controller of that data; we are the processor, acting only on your instructions, under a Data Processing Agreement available on request (see below). If one of your contacts has a question about being reached through Curviate, you're who they should contact first; email privacy@curviate.com if you need help routing it.

What we collect, and why

DataWhy
Account identity (name, email, sign-in method)Create and secure your account
Your LinkedIn credentialsOperate the actions you request
LinkedIn content returned by an API callFulfil that specific request, nothing more
API keys and connector (OAuth) authorizationsAuthenticate your API, CLI, MCP, or SDK requests
Billing detailsCharge you correctly and meet our tax obligations
Usage and security logsKeep the service reliable and abuse-free
Support messagesRespond to you
Website analytics, only if you opt inUnderstand how the site is used

We rely on our contract with you, our legitimate interest in running and securing the service, our legal obligations (tax law, for example), and, for analytics, your consent. We never sell your data or use it to train models.

Where it's processed, and who else touches it

Our infrastructure runs in the EU. Hosting: Railway. Database and auth: Supabase, Ireland. Email: Resend. Payments: Stripe. Network security: a DDoS-protection provider sits in front of our app and never sees or stores request content. LinkedIn connectivity: a third-party infrastructure provider that lets us execute LinkedIn actions on your behalf. Error tracking: Sentry, Frankfurt. Product analytics: PostHog, Frankfurt. Uptime monitoring: Better Stack.

We give the current, named list of every provider above to any customer who asks: security@curviate.com.

Data processing agreement

A data processing agreement under Article 28 of the GDPR is available to business customers on request. Email security@curviate.com and we will send you the current version.

Outside the EU

All customer LinkedIn data, account data, and telemetry are processed and stored exclusively in EU regions of our sub-processors. A few providers we rely on (Stripe and Sentry, for example) are headquartered outside the EU/EEA; where that applies, it's covered by their own GDPR safeguards, typically the EU Standard Contractual Clauses.

How long we keep it

DataRetention
Account and workspace dataWhile your account is active
Closed accountDeleted immediately and irreversibly; see Deleting your account below
LinkedIn credentialsUntil you disconnect that account
LinkedIn contentNot stored; any transient cache clears within 1 hour, never indexed, never used for training
API keysUntil you revoke or rotate them
Connector (OAuth) authorizationsAccess token ~1 hour; refresh token up to ~12 months, or until you revoke it, whichever comes first
Billing recordsAs required by German tax law, currently up to 10 years
LogsA short operational window; metadata only, never message content

The 12-month figure above is a server-side credential for a connected AI agent or app. It is not a cookie and doesn't touch your browser session; see Cookies below for that. You can see and revoke every connector from Authorized applications in your dashboard at any time.

Cookies

We keep cookies to a minimum, and ask before anything beyond the essentials runs.

Strictly necessary, no consent needed:

NamePurposeExpiry
cc_cookieRemembers your cookie choice12 months
curviate-themeRemembers light/dark mode (local storage, not a cookie)Persistent
sb-*-auth-tokenKeeps you signed inWhile active; cleared on sign-out

Analytics, only if you accept:

NamePurposeExpiry
_gaGoogle Analytics: distinguishes visitors2 years
_gidGoogle Analytics: distinguishes visitors24 hours
_ga_<container id>Google Analytics: persists session state2 years

No advertising cookies, ever. Accept and reject are equally easy, and you can change your mind any time via Cookie Preferences in the footer; we won't ask again for 12 months unless something material changes. Our LinkedIn connect flow and OAuth authorization screen never set anything beyond the essentials, so no banner appears there.

Connecting an AI agent or app

Curviate is built for AI agents and automated clients as much as for people. If you connect an app like Claude, or your own code, via an API key or an OAuth connector, it can act on your workspace within the access you gave it. What it does with anything it receives back, including what it sends to its own AI model, is between you and that provider; review its practices before connecting it. Review and revoke any connection any time from your dashboard.

Deleting your account

You can delete your account yourself, from Settings in your dashboard. It takes effect immediately and it cannot be undone. There is no grace period and nothing to restore afterwards, so export anything you want to keep before you start.

Deleting removes your sign-in identity, which frees your email address for reuse straight away, along with your profile, your workspace membership and settings, your API keys, and your seats. For any connected LinkedIn account, we instruct our infrastructure provider to delete it, and your access ends immediately. Records of the connection itself can remain in our systems; email privacy@curviate.com if you need those removed as well. LinkedIn content was never stored in the first place, so there is none of it to delete.

A few things are kept on purpose. We would rather name them than claim a clean sweep:

  • Billing records, for as long as German tax law requires. They hold plan, seat count, amount, and payment references; no name, no email, no LinkedIn data.
  • A record that the deletion happened, so we can show you or a regulator that we did it.
  • A security log of which requests were made, kept for 90 days and then removed automatically. It records that a request happened, never what was in it.
  • A one-way fingerprint, if you used a free trial, that lets us recognise a repeat trial. It holds no readable identifier and cannot be read back into your name, your email, or your LinkedIn profile.

Internal workspace identifiers can also remain in operational records such as queue entries and rate-limit counters. Those carry no name, no email, and no content. If you want to know exactly what is left for your own account, ask us at privacy@curviate.com.

Your rights

You can access, correct, delete, restrict, or object to your data, port it elsewhere, and withdraw consent at any time: email privacy@curviate.com. A copy of your data in a machine-readable format is available on request. We don't make automated decisions about you that have a legal or similarly significant effect. You can also complain to a supervisory authority; ours is the Landesbeauftragte für Datenschutz und Informationsfreiheit Nordrhein-Westfalen (LDI NRW), www.ldi.nrw.de, though you're free to complain to the one in your own country instead.

Keeping it secure

Credentials are encrypted and never logged, returned, or shared. LinkedIn actions run through native, humanized flows; full detail is on our Security & Compliance page. If a breach puts your rights at risk, we'll notify the authorities and you, as GDPR requires. Curviate isn't directed at, or offered to, anyone under 16.

Changes

We'll update this page when our practices change, and reset the cookie prompt if the change is material.

Contact