A mailer, member database, and so much more, for digital activism.
The Identity API is designed to get data into or out of Identity, and is for use by external applications.
The most common use case for the Identity API is to get an external Call To Action tool (often Speakout, but could be anything) to send data about actions taken by a user to Identity, such that Identity can record this data. See the Create Member Actions section for more information on using this API.
Another common use case is to allow an external Call To Action tool (again, often Speakout) to get details about a user (such as their name, email, zip or postal code, etc) so the user does not need to fill in these details again. See the Get Member Details section for more information on using this API.
Most requests require a token issued by the organisation using Identity to access the API features.
This API token can be included in a variety of ways, it can be included as a URL query parameter like api/member/details?api_token=YOUR TOKEN HERE
, as a BASIC auth header (with your token in the password field), or as a POST parameter api_token
POST domain/api/member/details '{"api_token": "YOUR TOKEN HERE", "other_parameter": "....", ....}'
Unauthenticated requests will return HTTP 403 Forbidden.
Identity API Tokens are stored in the api_users
table in the Identity
database. Because different integrations require access to different data/functionality, API users should be granted specific permissions. You can also generate an API token with super_admin
permission to access all APIs, but this is not recommended and will produce warnings in your logs. You can generate a new API user with access to member data (for example) using the Rails console:
denny@X1:~$ heroku run rails c --app identity-staging
Running rails c on ⬢ identity-staging... up, run.3525 (Standard-1X)
Loading production environment (Rails 5.2.1.1)
irb(main):001:0> APIUser.connection
[...]
irb(main):002:0> APIUser.create_with_permission!('members_api', name: 'Human Readable Name', active: true )
=> #<APIUser id: 9, name: "Human Readable Name", token: "8eca02ca77e7aa36f1e02f6b62cfddb990e2bc2c8efbb47cb9...", active: true, role_id: 7, created_at: "2019-02-15 14:57:45", updated_at: "2019-02-15 14:57:45">
For more information on API security and selecting the correct permission/s for your API user, refer to the Security documentation
Several API methods accept a cons_hash parameter, which is a standardised format of representing data about a person.
It can be used to update contact details, external ids, custom fields, and subscription statuses.
When providing a cons hash to update member details, all fields are optional. Provided fields will be used to attempt to identify an existing member (for example, identifying a member from their guid
, their email
, their phone_numbers
, etc). If a matching member cannot be found, a new member is created.
The structure is as follows:
{
guid: Int,
firstname: String,
middlenames: String,
lastname: String,
emails: [
{ email: String },
...
],
phones: [
{ phone: String },
...
],
addresses: [
{
line1: String,
line2: String,
town: String,
state: String,
postcode: String,
country: String
},
...
],
external_ids: {
"system_name" (String): "external_id" (String),
...
},
custom_fields: [
{
name: String,
value: String
}
...
],
subscriptions: [
{
id: Int or String, (internal id or slug of Subscription)
action: String, (either 'subscribe' or 'unsubscribe')
reason: String
}
...
],
entry_point: String
}
POST /api/member/details
One of (required):
guid
The member GUID token, present in the cookie guid on the organisation’s domainemail
The member’s email addressJSON containing details about the member corresponding to the identifier supplied. If no member is found matching the GUID then an empty JSON string will be returned.
Example request: POST { your deployment }/api/member/details '{"api_token": "1234567890abcdef", "guid": "abcdef1234567890"}'
Example response: '{"first_name": "Joe", "last_name": "Bloggs", "email": "joe@bloggs.com", "address": { ... }, .... }'
Example request: POST { your deployment }/api/member/details '{"api_token": "1234567890abcdef", "email": "joe@bloggs.com"}'
Example response: '{"first_name": "Joe", "last_name": "Bloggs", "email": "joe@bloggs.com", "address": { ... }, .... }'
POST /api/member_actions/create
api_token
: a valid Identity API Token which has been generated and assigned to the external application making this call. Identity API Tokens are stored in the api_users
table.cons_hash
: cons_hash object (see above).action_type
: the type of the action, eg. petition
, speakout
, donation
, poll
, etc.action_technical_type
: the system the action originated from and the action type, eg. speakout.38degrees.org.uk:poll
, brexitquiz.com:survey
, etc.exernal_id
: the identifier for this action from the system the action originated from. For example, actions coming from Speakout would usually use the id
column from the campaigns
table.action_name
: a human-readable name for this action.description
: an optional description for this action.create_dt
: a timestamp representing when this action was taken by the user identified in the cons_hash
.opt_in
: a boolean indicating whether a user should be opted in to the organizations mailing list. This defaults to true, but will be ignored if your Identity install has Settings.gdpr.disable_auto_subscribe
set to true (which in general it should be if your organization is subject to EU GDPR laws).consents
: a list of consents presented to the user when taking this action, and whether the user gave consent to these or not. Note that consents and matching public_id
s for them must be setup in the Identity database before you can use them in external systems. Read the User Consents doc for more background information on this.
[
{
public_id: 'privacy_policy_20180525',
consent_level: 'implicit',
consent_method: 'implicit',
consent_method_option: nil
},
{
public_id: 'email_opt_in_consent_20180525',
consent_level: 'explicit_opt_in',
consent_method: 'radio_buttons',
consent_method_option: "Yes, please email me about future campaigns"
},
{
public_id: 'sms_opt_in_consent_20180525',
consent_level: 'none_given',
consent_method: 'radio_buttons',
consent_method_option: "No, don't SMS me about future campaigns"
}
]
source
: source object
{
source: String,
medium: String,
campaign: String
}
metadata
: key-value info about the action
{
"user_agent": "Mozilla/blabla",
...
}
survey_responses
: responses to questions as part of an action
[
{
question: {
text: String,
qtype: String (e.g. 'text', 'radio_buttons')
},
answer: [ String, ... ]
}
]
200 OK or an error
Example request: POST { your deployment }/api/member_actions/create
{
"api_token": "1234567890abcdef",
"action_technical_type": "speakout:petition",
"external_id": "123",
"action_type": "petition",
"action_name": "2017 Petition to Save Our Bees",
"description": "Blurb from the petition....",
"cons_hash": {
"firstname": "Bob",
"lastname": "Geldof",
"emails": [ {"email": "bob@geldof.com"} ]
},
"source": {
"source": "directcomm",
"medium": "email",
"campaign": "bees-2017"
},
"opt_in": false,
"consents": [
{
"public_id": 'privacy_policy_20170101',
"consent_level": 'implicit',
"consent_method": 'implicit',
"consent_method_option": nil
},
{
"public_id": 'email_opt_in_consent_20180525',
"consent_level": 'none_given',
"consent_method": 'radio_buttons',
"consent_method_option": "No, don't email me"
}
],
"create_dt": "2017-01-09 16:45:12"
Example response: 200 OK
To allow cross origin login check (for example for an application requiring the current user to be logged into Identity), you can load /login_status
in an iframe. If your parent window’s origin is listed in Settings.app.cors_origins
then the iframe will postMessage to your parent window with the message { "logged_in": true/false }
.