Abenity Member API
The Abenity Member API is a RESTful interface that allows you to manage member access to the Abenity Perks program by performing single sign-on (SSO), deactivation, reactivation and renewal.
This API accepts form-encoded content in requests and returns JSON contents in its responses. The UTF-8 character set is used for everything.
API Usage is governed by the API Terms.
Contents:
Introduction
Getting Started
To get started developing with the Abenity Member API you will need to meet the following requirements:
- Have an active account. Sign Up Now.
- Have an API Key. This can be obtained from the Account Settings in your Back Office.
- Have saved your RSA Public Key (in SSH format) in your Abenity Back Office. This is required in order to use the Single Sign-On method.
Security
In order to provide our clients and their members with the most secure system, the latest encryption technology must be used in order to interact with our API. Currently, this means using TLS v1.2 or higher to encrypt your HTTPS connection to the API. If your system uses outdated encryption technology you will receive a HTTP "426 Upgrade Required" error response.
Sandbox Testing Environment
If you would like to test your API integration, please use our "sandbox". To use the sandbox, simply change the request domain from api.abenity.com to sandbox.abenity.com.
The sandbox is reset on a daily basis. Additionally, because the sandbox DOES NOT operate on the production environment, any operations performed on sandbox.abenity.com will not be reflected on api.abenity.com or other live applications, including the Back Office and Perks Program. That said, all API requests and responses will behave the same.
Authentication
API requests are authenticated by sending three parameters with every request. All three may be found in the Account Settings of your program's Back Office web site. These parameters are:
- api_username
- api_password
- api_key
Errors
Errors do happen, and when they do the API will respond with a status of fail and one or more error messages. The error message may be a string or an array of strings. Unfortunately, at this time, there is not a comprehensive list of error messages and responses.
Error responses will occur in the body of the JSON response. HTTP Status Codes are not currently used to indicate the nature of the error.
Example
# Request
curl -X POST https://api.abenity.com/v2/client/sso_member.json
# Response
HTTP/1.1 200 OK
{
"class": "client",
"method": "sso_member",
"status": "fail",
"error": "Invalid API authentication"
}
Rate Limit
There is no rate limit. However, if Abenity believes that an IP address is abusing the API, then the offending address may be blocked.
API Wrappers
API Wrappers for the Abenity Member API are available below in several languages. They are provided as-is and can be built upon and contributed to by and for the Abenity community. These packages handle the necessary functions of encrypting the Payload, generating the encrypted Cipher, Iv, and Signature, and submitting the CURL request to the Abenity Member SSO endpoint. We recommend using one of these packages to reduce your integration time and facilitate updates.
Video tutorials are currently offered for the PHP and C# packages. These are informal demonstrations that will have you performing a Single Sign-On in under 10 minutes.
C# Walk-through
PHP Walk-through
Methods
Single Sign-On (SSO)
POST /v2/client/sso_member.json
When requesting the SSO resource, the API will create/validate the member and respond with a limited-time, tokenized URL that can be used within 60 seconds to log in to the program.
Because of the steps required to protect the Personally Identifiable Information (PII) contained within the request, the algorithm to generate the SSO parameters is complex. This process employs symmetric and asymmetric cryptography in order to protect the content and to verify that it is coming from the intended sender. Your software will need to be able to perform encryption using the 3DES (CBC Mode) and RSA (PKCS #1) algorithms.
Public Key
In order to verify that the message is coming from the intended sender, you will need to generate a public/private key pair. The private key will be used to sign your message, and the public key will be used by Abenity to verify your signature. You may generate the key using the ssh-keygen utility available on most systems.
ssh-keygen -t rsa -b 2048 -C "your_email@example.com"
Sample Public Key in ssh-rsa format:
ssh-rsa AAAAB3NzaC1yc2EAAAAB...truncated...fCbkw7hUPeE+FE= your_email@example.com
Once you have generated your public key, add it to your Abenity Back Office in order to have it associated with your Abenity program. You will not be able to use the SSO method until this step has been completed.
Implementation Overview
At the heart of the SSO request is the Payload, consisting of your member's profile which contains their name, email, unique ID and other information.
All API requests are required to use the HTTPS protocol, however the Single Sign-On process is constructed in such a way that it could be sent securely over an unencrypted channel. To this end, the member profile is encrypted using the 3DES encryption algorithm, which requires an initialization vector and key. The Initialization Vector is sent as part of the request. The 3DES key must be encrypted using the asymmetric RSA algorithm so that only Abenity may decrypt the 3DES key and Payload. The encrypted 3DES key is referred to as the Cipher.
Finally, in order to verify that the message came from the intended sender, a cryptographic Signature is performed during the construction of the payload.
Throughout this process base64-encoding and URL-encoding are performed to ensure that no data is mangled during the HTTPS transmission process.
Parameters
All parameters are required unless specifically marked as optional.
Parameter | Definition | Example |
Cipher | The Cipher is the asymmetrically-encrypted value of the symmetric key used to encrypt the Payload. Without the Cipher, the Payload cannot be decrypted. The Cipher should be built by (A) using Abenity's public key to perform RSA-encryption on the symmetric key used by the 3DES encryption of the Payload String, then (B) applying base64-encoding to the result of A, and then (C) URL-encode the result from B, and then (D) append the string "decode" (this is a convention used to indicate the current state of the message). | hIfKGD3C8zwQ8ictLN19e4bB8tnhPw%2BlTjcfo4c2N1ZalxjNlIptHOxZFAIEabyP4KAUMdMwsq88Kb4CoPpki0y6fcqrbVufmcNFHNhzW9Ihuiu4JF1dNlMw%2B8Ac1n9acD9kuugbl3NcMbB73OQrOaelXZILIBk8ekfil9l8Y3A%3Ddecode |
Iv | The Initialization Vector (IV) is used for the symmetric encryption/decryption of the Payload String. For the highest level of security, the IV should be randomly generated for every request. Like the other parameters, this value should be base64-encoded, then URL-encoded, and then have the string "decode" appended. | QbuI5iOPYDY%3Ddecode |
Payload | The Payload is the 3DES-encrypted value of a Payload String. A Payload String is a Member Profile represented as a key-value pair string (e.g. firstname=John&lastname=Smith). This is essentially the content of the request, which contains the member's name, email, etc. Symmetric encryption relies on an Initialization Vector (IV) and a Key. With these two resources, a symmetrically-encrypted message may be decrypted. The IV is sent as a different request parameter and the Key is the decrypted value of the Cipher parameter. The Payload should be built by (A) creating a key-value pair string of a Member Profile, and then (B) encrypting this using the 3DES algorithm with an Initialization Vector and symmetric key, and then (C) applying base64-encoding and then (D) URL-encoding, and then (E) appending the string "decode". The Member Profile is made up of these key-value pairs:
| pyKMcUSY2KmUz2IC9jBWyXf3N1K%2F6alBwqZxzyKbkhA2X9Yo6Jg%2BQmS3Y6vE3P2G1vcuI3RCEuE%2FcwXcMONdlSVo%2FnlaPSd3EPGqjeLcisZ6VYkMgIGNqhPQAmbTYOBe%2F7HAv8NWaUQXukM2NtBCiVpL0IyhuOJ4iWeP5PUecuVUjtHmnW%2F7C2yBFMBN8ohGvwrwOsm98emsRt2HtFDRP8vDMv0qlGdUEhw85nY2iJ4r5qI7bqB6vbCCAGm2BVTTJUYJVOtLxC53wpcCYZ2Py9nqRsQjjnNTRU9ujmjsA6A%3Ddecode |
Signature | The Signature is the result of an RSA signature on an MD5 hash of the payload. Because this is encrypted with the sender's private key, the sender's public key can be used to verify that the Payload was received without any modification by any 3rd parties. Important: The signature should be performed on the Base64-encoded, encrypted Payload String (the result of Step C in the Payload creation). The result of that operation should then be prepared for HTTP transmission by applying base64-encoding, URL encoding and appending "decode". | CwcxvNQ%2Fkv79GWMX82%2BlyCpJ1%2B27nmGcXf7oKGB1TNZNkvmyM0YLxIV%2BnzuYSwBr3IZ4NFHtLgzv2rnpFgpOWePpZztLqqW6TEF1uU8nT0aQkcxITz5cNPLdrvHM4zTerkqmK9TWEB4BXTCcas6mRFxhukX8FI6rNIIBmqDo8wQ%3Ddecode |
Example
# Request
curl -X POST https://api.abenity.com/v2/client/sso_member.json \
-d "api_username=acme" \
-d "api_password=abc123" \
-d "api_key=RmNaMjMuTTR4c010WG1US21EQTRzc0xDa0VuWWk6" \
-d "Payload=nZFtNx2UvcqRPq6GWljA65sFKB5WxCSEf3Kl%2FbNJiwET8%2BbSpvdd2ge1FwksItlPveXBOA0SIVkiyqaMW0wRPIzBw7V%2FYXCS6QBiDwE9gt21aYNd9TEI3dyxJU8P8yuZTNQRuSN19bO55C34IlddCcM3K2LJ49E4%2Bd9AtpE%2FpJ2RtBEYuiwDjm7qT6fSY2tEtlDh8o7pH92Xsh0%2FRSaQ5Yv8KmkxSOBSUXhoa68Poj4gFXbF6t9p7ojv%2ByVQj9MekHtiG5hstnENlp9qybpNVGF8merspAQEEns1LZRusd0%3Ddecode" \
-d "Cipher=i14NtABfPqCvIw%2BsqzoUFBbfybcOU0ALt7Xlv6KXixdAVSX3xfFZ%2FMtp9coTV6al1twfaSaSm1qLgEWqOFuJKngXQM2JIQqxsw6kxwoXxZNNpxX3UaJ0M7VetbfEWNP7BPOpQ8jajaK%2F7ViFNeznMc6FP7D3d6bZoGsYF9Wcmfc%3Ddecode" \
-d "Signature=VAOAZU5oWutzn%2FKph8UPALrS9zCovP%2BlC5T%2FiJmU%2B3nqbI%2FV8OEdKJ3Yg7odQZQONJxPAe6Oc9MgQpEo7qjv1fYx9z1%2FnQccqUjknT2BqlQSeQRZSbfWR11wuyi9vPChLMU3mwc4ssc1KyI3MctMwXtVW3aD8YyuXkXxQUsWAqQ%3Ddecode" \
-d "Iv=x6rDH5ugCYg%3Ddecode"
# Response
HTTP/1.1 200 OK
{
"method": "sso_member",
"status": "ok",
"data":
{
"token": "vGPUf5JHvlAxFPxYNGFq7J6VvDESRGLI",
"token_expiration": "Wed, 25 May 2016 01:44:49 -0500",
"token_url": "https:\/\/acme.abenity.com\/discounts\/process\/login?token=vGPUf5JHvlAxFPxYNGFq7J6VvDESRGLI"
}
}
Common Error Responses
The following is a list of common, but not all, error responses that could be received.
Code | Key | Message |
NA | Cipher | "Missing value for `Cipher` (case-sensitive)" - This indicates that the input parameter was not correctly received. |
NA | Iv | "Missing value for `Iv` (case-sensitive)" - This indicates that the input parameter was not correctly received. |
NA | Payload | "Missing value for `Payload` (case-sensitive)" - This indicates that the input parameter was not correctly received. |
NA | Signature | "Missing value for `Signature` (case-sensitive)" - This indicates that the input parameter was not correctly received. |
NA | NA | "Encryption Signature Failed" - This indicates that the Signature could not be verified. This means that there was a programming error or that the Payload was modified in transit. |
NA | signature | Possible Values
|
2001 | member | "New Member could not be created" - This error is triggered if a new member cannot be registered, usually because of a username conflict with an existing record. Prior to returning this error, Abenity will have tried several attempts to create a unique username by using the user's local-part of their email address (the part before the "@" sign) and a random 2-digit number. If all attempts fail, then you will receive this error. If this happens, which should be extremely unlikely, you have 3 options: (1) try again (which would generate new random usernames) (2) Set the username explicitly or (3) log the failure and contact Abenity Support. |
2002 | unauthorized | "The provided username is not a member of your program" - This error is triggered if the member profile is found but not assigned to the program issuing the request. |
2003 | unauthorized | "Member account is deactivated" - This error is triggered if a SSO attempt is made for a member that does not have login privileges. The user may have login privileges reinstated using the Reactivate Member method. |
2004 | unauthorized | "Member account is locked" - This error is triggered if the requested member's account has been locked due to too many failed login attempts. Abenity Support must be contacted to unlock the account. |
Deactivate
POST /v2/client/deactivate_member.json
Disable a member from logging in to Abenity programs.
Parameters
Parameter | Definition | Example |
client_user_id | This is the unique identifier for the member within the domain of the Abenity client's program. This matches the identifier that was used to create the member's record in the SSO API request. | ID12345 |
send_notification (Optional) | Set to 1 to send a notification email to the member. If no value is sent, then no notification email will be sent. If the member does not have an email address associated with their account, then no email will be sent regardless of the value. | 1 |
Example
# Request
curl -X POST https://api.abenity.com/v2/client/deactivate_member.json \
-d "api_username=acme" \
-d "api_password=abc123" \
-d "api_key=RmNaMjMuTTR4c010WG1US21EQTRzc0xDa0VuWWk6" \
-d "client_user_id=ID12345" \
-d "send_notification=0"
# Response
HTTP/1.1 200 OK
{
"class": "client",
"method": "deactivate_member",
"status": "ok"
}
Delete Member
DELETE /v2/client/delete_member.json
Delete a member from the Abenity program.
Parameters
Parameter | Definition | Example |
client_user_id | This is the unique identifier for the member within the domain of the Abenity client's program. This matches the identifier that was used to create the member's record in the SSO API request. | ID12345 |
Example
# Request
curl -X DELETE https://api.abenity.com/v2/client/delete_member.json \
-d "api_username=acme" \
-d "api_password=abc123" \
-d "api_key=RmNaMjMuTTR4c010WG1US21EQTRzc0xDa0VuWWk6" \
-d "client_user_id=ID12345"
# Response
HTTP/1.1 200 OK
{
"success": true
}
Reactivate
POST /v2/client/reactivate_member.json
Re-enable a member to log in to Abenity programs.
Parameters
Parameter | Definition | Example |
client_user_id | This is the unique identifier for the member within the domain of the Abenity client's program. This matches the identifier that was used to create the member's record in the SSO API request. | ID12345 |
send_notification (Optional) | Set to 1 to send a notification email to the member. If no value is sent, then no notification email will be sent. If the member does not have an email address associated with their account, then no email will be sent regardless of the value. | 1 |
Example
# Request
curl -X POST https://api.abenity.com/v2/client/reactivate_member.json \
-d "api_username=acme" \
-d "api_password=abc123" \
-d "api_key=RmNaMjMuTTR4c010WG1US21EQTRzc0xDa0VuWWk6" \
-d "client_user_id=ID12345" \
-d "send_notification=0"
# Response
HTTP/1.1 200 OK
{
"class": "client",
"method": "reactivate_member",
"status": "ok"
}
Frequently Asked Questions
Q: What resources are required to integrate the Single Sign-On API?
A: In order to integrate SSO into your application, you will need at least one developer who is proficient in your application environment code and who is either proficient in one of the languages supported by our API wrappers or proficient enough in the language of your environment to develop an integration without use of the API wrapper code.
Q: Does Single Sign-On work with Wordpress
A: Wordpress is open-source software written in PHP, so it is possible to integrate Abenity's PHP API Wrapper with the Wordpress codebase; however it will require custom development by someone familiar with the Wordpress environment. Abenity does not have an officially supported Wordpress Plugin.
Q: If I'm using SSO, how do my members log in to native Perks apps (iOS, Android, etc.)?
A: The member will need to use their Abenity username and password, not the credentials used via SSO through your site. A member can manage their Abenity-assigned username and change their password under their Profile in the perks program.
Q: When using SSO, can I "deep link" into the Perks program?
A: Yes. You may deep link into the Perks program by adding a custom query string parameter to the login link. For example, if you'd like to link to the Movies category, then you can add page_request=/discounts/category/Movie_Tickets to the end of the `token_url` returned from `sso_member`. For example, https://acme.abenity.com/discounts/process/login?token=vGPUf5JHvlAxFPxYNGFq7J6VvDESRGLI&page_request=/discounts/category/Movie_Tickets. This will immediately redirect to https://acme.abenity.com/discounts/category/Movie_Tickets after logging in.
Q: Can I use the API to perform a bulk import of my members?
Yes, you may use the Single Sign-On API method to register your members. If you do that you can simply loop through all of your members and perform the SSO operation one at a time. If you use the SSO method this way, you simply monitor the API response for errors, but can otherwise ignore the login link and token in the response.
Q: What is Abenity's Public Key?
Abenity's public key is required to interact with the Single Sign-On API method. The PHP package contains the key already, so if you use that package you won't need to define the key yourself. The C# package looks for the PEM-formatted key in a file that you will need to provide.
Key in SSH Public Key Format:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC8NVUZUtr2IHiFoY8s/qFGmZOIewAvgS4FMXWZ81Qc8lkAlZr9e171xn4PgKr+S7YsfCt+1XKyo5XmrJyaNUe/aRptB93NFn6RoFzExgfpkooxcHpWcPy+Hb5e0rwPDBA6zfyrYRj8uK/1HleFEr4v8u/HbnJmiFoNJ2hfZXn6Qw== abenity.com
Key in PEM Format:
PKCS#1 RSA Public key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBALw1VRlS2vYgeIWhjyz+oUaZk4h7AC+BLgUxdZnzVBzyWQCVmv17XvXG
fg+Aqv5Ltix8K37VcrKjleasnJo1R79pGm0H3c0WfpGgXMTGB+mSijFwelZw/L4d
vl7SvA8MEDrN/KthGPy4r/UeV4USvi/y78ducmaIWg0naF9lefpDAgMBAAE=
-----END RSA PUBLIC KEY-----
PKCS#8 RSA Public key (For Java)
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8NVUZUtr2IHiFoY8s/qFGmZOI
ewAvgS4FMXWZ81Qc8lkAlZr9e171xn4PgKr+S7YsfCt+1XKyo5XmrJyaNUe/aRpt
B93NFn6RoFzExgfpkooxcHpWcPy+Hb5e0rwPDBA6zfyrYRj8uK/1HleFEr4v8u/H
bnJmiFoNJ2hfZXn6QwIDAQAB
-----END PUBLIC KEY-----