Retention and deletionMenu
On this page

Retention and deletion

Updated

Learn what Kirora keeps and for how long, from message content and events to webhook deliveries, and what deleting a contact removes.

Kirora keeps each kind of data for a set period, then deletes it or removes the personal data from it. This page lists what is kept, for how long, and what deleting a contact removes, so you can answer a customer’s question or a data-protection review without reading every guide.

Periods are in days and counted from when the data was created, unless a row says otherwise. Removal runs in the background, so data can remain readable for a short while after its period ends.

Periods set by the plan

Three periods depend on the owner’s plan:

  • Event retention: 30 days on Free, up to a year on paid plans, counted from the event’s occurredAt. An event’s expiry (expiresAt) is fixed when it is stored, so a plan change moves only the expiry of events stored afterwards.
  • History period, for the message log: from 90 days to two years.
  • Audit period, for the audit log: from 30 days to two years.

For 30 days after a plan changes, nothing is removed under the new plan’s history or audit period, so moving to a plan with a shorter one does not take history away the same day.

What is kept

Data Kept Then
Contact profile, with its attributes and topic choices Until the contact is deleted See Deleting contacts
Consent changes Until the contact is deleted Deleted with the contact
Events The event retention, until the event’s expiresAt Deleted. listEvents and listContactEvents no longer list them
Refused events in the event log 30 days Deleted
Events under a name you deleted with deleteEventName Until the background removal reaches them Deleted
Message status and timestamps As long as the workspace After the history period, the message is anonymised (below) and keeps its status
A transactional message’s content The workspace’s content period, from when it was accepted: 30 days by default, set from 0 to 90 days in the workspace settings Removed. getMessageContent returns 404 CONTENT_NOT_RETAINED
A sensitive transactional message’s content Until sending finishes Removed. It returns 404 CONTENT_NOT_RETAINED
Attachments of a transactional email Until sending finishes Deleted once it is sent; a cleanup job removes those of a message that won’t send
Per-recipient data on a campaign trigger Until sending finishes Removed
A message export file 7 days, given in the export’s expiresAt Deleted. The export reads expired, and its download returns 410 EXPORT_UNAVAILABLE
A delivered webhook delivery 30 days, without its body Deleted
A failed webhook delivery 90 days, with its body, so you can resend it Deleted. Before that, once the body is gone, redeliverWebhookDelivery returns 409
A segment’s daily size 400 days Deleted
The request log in the dashboard 31 days Deleted

Messages after the history period

A message older than the history period is anonymised, not deleted, so campaign and journey totals and the reports stay correct. Anonymising removes:

  • the link to the contact: contact reads null;
  • the address it went to (recipientEmail) and the bounce detail;
  • what was sent: the email and push content and any data sent with it;
  • the provider’s message ids.

The message keeps its status, its timestamps, channel, messageType and where it came from (campaign, journey). An anonymised message no longer matches a recipient filter on listMessages.

Idempotency keys

Key Kept
The shared Idempotency-Key on any POST The first response is kept for 24 hours
A transactional send’s key As long as the message it created, so a late retry is still recognised
A tracked event’s key A year from the event’s occurredAt, even when the event itself is kept for less
A campaign trigger’s key As long as what the trigger created

After a key is gone, the same key starts a new request. A backdated event’s key is therefore kept for less time than one tracked as it happened. See Idempotency.

Deleting contacts

For a right-to-erasure request, deleteContact (DELETE /v1/contacts/{id}, scope contacts:delete) deletes one contact, named as on any contact route: Kirora’s id, or your own id or the email address with idType. It answers 204, 404 for a contact that does not exist, and 409 CONTACT_SEND_IN_PROGRESS while a message to the contact is being handed to a provider, which takes seconds: retry shortly. A message waiting to be retried does not hold it up; it is skipped (contact_deleted); a push that already reached one of the contact’s devices is marked sent, and one a push service refused is marked failed, as it would have ended anyway.

Terminal
curl -X DELETE "$KIRORA_API_URL/v1/contacts/customer-4821?idType=externalId" \
  -H "Authorization: Bearer $KIRORA_API_KEY"

deleteContacts (POST /v1/contacts/delete) deletes up to 100 at once, each named by contactId, externalId or email, and reports an outcome for each: deleted, not_found, or send_in_progress (retry that one shortly). An agent key can do neither.

Terminal
curl "$KIRORA_API_URL/v1/contacts/delete" \
  -H "Authorization: Bearer $KIRORA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: delete-request-2026-10-23-001" \
  -d '{ "contacts": [ { "externalId": "customer-4821" }, { "email": "[email protected]" } ] }'
Deleting a contact What happens
Deletes The contact, its events, list memberships, consent changes and journey enrollments, the messages its journey enrollments sent, and its pending and failed webhook deliveries, which are then never sent or resent
Anonymises Its campaign and transactional messages, as after the history period: no address, content or provider ids, and nothing that links them to the contact. Its conversions are kept for revenue figures, without the link
Keeps Address suppressions, so a deleted address that is imported again is still not mailed. Campaign, journey and report totals

A deleted contact cannot be restored. A contact created later with the same email or externalId is a new contact with no history.

To answer a right-of-access request before deleting, getContactExport (GET /v1/contacts/{id}/export) returns everything held about one contact. Data past the periods above is no longer held, so it is not in the export.

Deleting a workspace

A partner deletes a workspace it manages with deleteWorkspace. Sending stops at once, and after a grace period, 14 days by default, the workspace and everything in it is deleted for good. Until then, cancelWorkspaceDeletion keeps it.

Next steps