A contact's consent history
const url = 'https://api.threadkite.app/v1/contacts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/consent-history';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://api.threadkite.app/v1/contacts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/consent-history \ --header 'Authorization: Bearer <token>'Every change to their consent on every channel, and every confirmation of it, newest first: who or what made it, when, how, and the wording they saw. Includes the history of contacts merged into this one. Proof of consent for UK and EU GDPR and PECR.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Responses
Section titled “Responses”object
object
The contact it was recorded for: this contact, or one merged into it (its history is part of this one)
The name of the merged contact it was recorded for; null when it was recorded for this contact
email, sms, whatsapp or phone
The decision after it. pending_opt_in: an opt-in from someone we could not verify for a contact who had opted out, kept but not applied
Who or what made it
What happened, in plain English
When the decision was made
When Threadkite recorded it
The team member who made it
Their name, unless they have left
The API key’s name, unless it was deleted
The message behind it (the STOP text, the form lead, the email complained about)
For merges: the other contact
The word they sent
The consent wording shown, exactly, with the boxes ticked ([x]) and not ([ ])
A version or hash that pins the wording
The page the form was on
A keyed hash of the network it came from (never the address)
Anything else kept with it
Example
{ "events": [ { "recordedForName": null, "channel": "sms", "purpose": "marketing", "state": "opted_out", "previousState": "opted_in", "source": "inbound_keyword", "summary": "Opted out by replying STOP to a text", "formName": "Leeds website", "keyword": "STOP" } ]}Missing or invalid API key
object
Stable machine-readable reason
With code invalid: every problem with the request, by field (message is the first)
object
Dotted path inside the item, e.g. attributes.price.amountMinor
Example
{ "statusCode": 403, "code": "forbidden", "message": "You do not have permission to do that.", "errors": [ { "message": "Enter the make" } ]}The organisation is on the Free plan (code upgrade_required)
object
Stable machine-readable reason
The feature that needs Pro
Where to upgrade or pay, in the web app
Example
{ "statusCode": 402, "code": "upgrade_required", "message": "Connections are part of Pro. Upgrade to connect texts, calls and more.", "feature": "extraSeats", "upgradePath": "/settings/billing"}The key does not have the scope (or the person the permission)
object
Stable machine-readable reason
With code invalid: every problem with the request, by field (message is the first)
object
Dotted path inside the item, e.g. attributes.price.amountMinor
Example
{ "statusCode": 403, "code": "forbidden", "message": "You do not have permission to do that.", "errors": [ { "message": "Enter the make" } ]}object
Stable machine-readable reason
With code invalid: every problem with the request, by field (message is the first)
object
Dotted path inside the item, e.g. attributes.price.amountMinor
Example
{ "statusCode": 403, "code": "forbidden", "message": "You do not have permission to do that.", "errors": [ { "message": "Enter the make" } ]}Rate limit reached
object
Stable machine-readable reason
Seconds until another request will be accepted
Example
{ "statusCode": 429, "code": "rate_limited", "message": "Too many requests. Each key can make 120 requests a minute; try again in 12 seconds.", "retryAfter": 12}