Perkville Version 2 API
Jump right into the API documentation. We're always happy to help out with any questions you might have. Drop us a message at api@perkville.com
Client Registration
Before making requests to the Perkville v2 API, clients must first register with Perkville. Once the registration form has been filled out and submitted, we will email the new client id and secret to the contact email that is provided.
New clients will only be allowed to request the PUBLIC scope (see the scopes section below). A Perkville representative will contact the person included in the client registration form to verify the authenticity of the developer and discuss what permissions your application will need from the Perkville API.
RegisterAuthentication
When using Perkville V2 API, you must authenticate with a bearer token. A bearer token represents a connection between you—the API client—and the end user. When you make an API request with a bearer token, you're essentially performing an action on behalf of a specific user.
You can generate a bearer token by putting a user through the OAuth 2 authorization code grant flow, which is described in detail below.
Scopes
The scopes listed below can optionally be requested in the authorization code request. When the access token is given back to the client, a list of scopes applicable to the access token is included in the request.
To understand what these scopes mean, one must understand the two types of users within Perkville: There are regular customers and there are business administrators. Regular customers only use Perkville to checkout their point balance, refer their friends, redeem rewards, etc. Business administrators also use Perkville in an administrative capacity -- they need to give points to their users, redeem points on behalf of their customers, etc. Scopes are partitioned along those lines.
name | description |
PUBLIC | Grants read-only access to public information |
USER_CUSTOMER_INFO | Grants read-only access to user's contact information, business connections, and vouchers. Grants ability to mark a voucher as "Used". |
USER_REDEEM | Grants ability to redeem a user's earned points |
USER_REFERRAL | Grants ability to create a referral to a users connected businesses |
ADMIN_CUSTOMER_INFO | Grants read-only access to a user's customer's contact information and business connections. |
ADMIN_CUSTOMER_REDEEM | Grants read access to a user's customer's vouchers. Grants ability to mark customer's vouchers as "Used". Grants ability to redeem points on behalf of customers. |
ADMIN_CUSTOMER_GRANT_POINTS | Grants ability to grant points to a user's customers and invite new customers to Perkville. |
ADMIN_CUSTOMER_REFERRAL | Grants ability to create a referral on behalf of two users. |
ADMIN_PERK | Grants ability to create and edit perks within a business' rewards program. |
ADMIN_LOCATION | Grants ability to create and edit a business's locations. |
ADMIN_IDENTIFY_USER | Grants the ability to implement the Identify User Flow |
You should request only those scopes which are absolutely required for your application. For example, if you are writing a point of sale integration, which is mostly concerned about posting transactions on behalf of business administrators, then you should probably request the following scopes: PUBLIC, ADMIN_CUSTOMER_INFO, ADMIN_CUSTOMER_REDEEM, ADMIN_CUSTOMER_GRANT_POINTS, ADMIN_CUSTOMER_REFERRAL, ADMIN_PERK. If you're writing a mobile app which allows users to redeem points and look up their point balance, then you should probably request these scopes: PUBLIC, USER_CUSTOMER_INFO, USER_REDEEM, USER_REFERRAL.
Accessing Endpoints
Once you have a bearer token, you're ready to access an endpoint. Below, you'll find details on each of the endpoints which are included in our API. Click on the "Example" button to see a sample request/response, along with the format of the returned data.
Authorization Header
When making a request, you must include a bearer token in the Authorization header of the HTTP request. For example:
Authorization: Bearer OjfXMYim1ttM4v7iA0RLhv6OWyss07
Filtering
Primary Key
Many resources can be filtered. For example, the Connection resource can be filtered by "user". That request would look like this:
GET https://api.perkville.com/v2/connections/?user=1234This would query for those Connection objects which belong to the user with the ID 1234.
Combining Filters
Filters can be combined. For example, if you want to look up those "Connection" resources which belong to the user above, 1234, who also belong to business 889, the query would look like this:
GET https://api.perkville.com/v2/connections/?user=1234&business=889
"In" filter
Querying for specific sets of values can be done using an __in filter:
GET https://api.perkville.com/v2/perks?business=889&classification=REDEEM&type__in=STANDARD,TIME_BONUS,FREQUNCY_BONUSThis would query for all active redeem perks at business 889 with the "type" STANDARD, TIME_BONUS, or FREQUENCY_BONUS
Greater Than/Less Than Filter
Querying for a range of values can be done with __gt, __lt, __gte, or __lte filters.
GET https://api.perkville.com/v2/transactions/?user=me&biz=889&transaction_dt__gte=2016-11-01%2000%3A00Z&transaction_dt__lte=2016-12-01%2000%3A00ZThe above query would include only those transactions that happened after 2016-11-01 00:00 UTC and before 2016-12-01 00:00 UTC. We strongly suggest adding UTC offset or Z when filtering on dates.
Relational Queries
Certain fields support relational queries:
GET https://api.perkville.com/v2/transactions/?user=me&biz=889&transaction_dt__gte=2016-11-01&perk__classification=REDEEMThe above query would only return transactions that had perks with the classification "REDEEM". Available to fields with the note "SUPPORTS RELATIONAL QUERIES"
The documentation below specifies what filters are allowed on each resource.
Note that filtering only applies to GET requests.
Pagination
Requests on resources that return multiple items will be paginated to 20 items by default. You can set up a
custom page size with the ?limit
parameter to return more or less items based on your preferences.
To page through to a particular set of records, use the ?offset
parameter followed by the number of
records you want to skip. An example request might look like this:
GET https://api.perkville.com/v2/businesses/?offset=10
The pagination parameters can be used together to set a custom page size for your request along with the number of records you would like to skip over. See this example query as a reference:
GET https://api.perkville.com/v2/businesses/?limit=10&offset=10
Please note that offset=0
returns a set of records that start with the very first record. If you
request offset=10
a set of records will be returned that start with the eleventh record and continue
in sequence until the number specified in the limit is reached.
Handling Errors
Perkville uses conventional HTTP response codes to indicate if something went wrong with your request.
HTTP Status Code | Description |
200 | Success |
201 | Success, object created |
202 | Accepted, object updated |
204 | No Content, object deleted |
400 | Bad Request: The request has a problem that can usually be corrected. Could be a syntax error, validation error, or some other correctable issue. |
401 | Unauthorized: Something is wrong with your credentials. We don't know who you are. |
403 | Forbidden: We know who you are, but you're not allowed to do that thing. |
500 | Server Error: Something went wrong on Perkville's server. |
501 | Method Not Implemented: You've requested a resource using an HTTP verb that we don't support. |
Furthermore, when we return a 4XX-type response, we include additional information in the response body, in the following form.
{ 'error_type': 'error_type_here', 'errors': { 'field_name_here': [ { "code": "erorr_code_here", "message": "Long-form, English explanation of what went wrong and how to fix it" } ] } }
error_type is always one of these values--
error_type | Description |
oauth_error | Something went wrong in the OAuth flow, or related to the OAuth credentials themselves. |
authorization_error | The request failed because you accessed something that you weren't allowed to access. |
invalid_request_error | 9 times out of 10, this is a correctable validation error of some kind |
unknown_error | Something that we haven't accounted for occurred |
errors contains one or more JSON objects explaining in detail what went wrong.
The object keys in "errors" tell you the name of the field that had the problem. If the problem was with the entire request, then "__all__" is used in the field name.Here's a complete example of an error response:
{ "error_type": "invalid_request_error", "errors": { "user_email": [ { "code": "invalid", "message": "Enter a valid email address.", } ], "__all__": [ { "code": "required", "message": "user and user_email were not supplied; Supply exactly one of them." } ] } }
Agreement Version
An Agreement Version is a specific version of a Business' Agreement, which may reflect updated language for a given agreement.
GET
GET /v2/agreement-versions/{AGREEMENT_VERSION_ID}/
Example
Example Request
curl https://api.perkville.com/v2/agreement-versions/1/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "agreement_id": 1, "agreement_internal_name": "Referral offer acceptance terms", "agreement_type": "REQUIRED-OPT-IN", "agreement_version_id": 1, "business": "/v2/businesses/2/", "created_dt": "2020-02-06T23:27:05.641334+00:00", "last_mod_dt": "2020-02-06T23:27:05.641334+00:00", "resource_uri": "/v2/agreement-versions/1/", "text": "This is the text of the agreement version", "version": "2020.02.06-23.27.05" },
Restrictions
Required scopes:
- PUBLIC
Required Filters
GET requests to the agreement version endpoint that do not specify an AGREEMENT_VERSION_ID are required to append an agreement or business filter. Using an "IN" style query with the business filter is also not allowed with this resource.
Examples of VALID requests:
/v2/agreement-versions/55/ /v2/agreement-versions/?agreement=1125 /v2/agreement-versions/?business=6 /v2/agreement-versions/?business=6&agreement__in=1123,1125
Examples of INVALID requests:
/v2/agreement-versions/ /v2/agreement-versions/?business__in=5,6
Fields
Property Name | Type | Filterable | Description |
agreement_version_id | int | ✓ | The agreement version ID. |
agreement_id | id | ✓ | The agreement to which this version belongs. |
agreement_internal_name | string | The internal name of the agreement to which this version belongs. This is not displayed to end-users, but is used to identify the agreement in the Perkville system. | |
agreement_type | string | The type of agreement, which can be either "REQUIRED-OPT-IN" or "OPTIONAL-OPT-IN". | |
business | Business | ✓ | The business to which this agreement version belongs. |
version | string | The version of the agreement, as specified by the business. | |
text | string | The text of the agreement version. | |
is_active | boolean | Whether this agreement version is active. Only one agreement version for an agreement can be active at a time. | |
created_dt | datetime | The date on which this agreement version was created. | |
last_mod_dt | datetime | The date on which this agreement version was last modified. |
POST
PATCH
DELETE
Business
A "Business" is a Perkville client, and represents a single rewards program for a real world business.
Users can have a Connection to a Business, which represents the customer relationship between the User and the Business, and includes point balance.
Businesses have Locations, which are the physical locations of the Business.
Businesses also have Perks, which are the collection of rules defining how many points a User earns for various activities as well as how many points a User can spend in order to earn a particular reward.
GET
GET /v2/businesses/{BUSINESS_ID}/
Example
Example Request
curl https://api.perkville.com/v2/businesses/4/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "app_connection_message": "", "brand_color": null "business_id": 4, "categories": [ { "category": "Restaurant", "category_id": 36, "resource_uri": "/v2/categories/36/", "subcategory": "Quick serve" } ], "fine_print": "Points not valid for cash back (unless required by law). Must use in one visit. Does not cover tax or gratuity. Cannot be combined with other offers.", "homepage_url": "http://www.example.com/", "locations": [ "/v2/locations/1/", "/v2/locations/2/" ], "name": "Tacos el Carbon", "promotions": [ "/v2/promotions/3/" ], "perks": [ "/v2/perks/5/", "/v2/perks/8/", "/v2/perks/9/" ], "perkville_url": "https://www.perkville.com/biz/4/", "resource_uri": "/v2/businesses/4/", "rewards_program_name": "Tacos el Carbon Rewards" }
Restrictions
Required scopes:
- PUBLIC
Fields
Property Name | Type | Filterable | Description |
business_id | int | ✓ | The business ID |
categories | Category[] | An array of Category objects, which indicate what kind of business this is. | |
fine_print | string | Business level fine print that contains any restrictions on use of this business' rewards program. | |
homepage_url | string | The url of this business' home page | |
locations | Location[] | An array of Location resources, which are the physical locations of this business. | |
name | string | ✓ | Name of the business |
logo_url | string | A link to the logo of this business | |
brand_color | string | A Business specified hex color for use with branding elements | |
brand_secondary_color | string | A Business specified hex color for use with branding elements | |
promotions | Promotion[] | An array of Promotion resources, which are the collection of promotional perks a business offers. | |
perks | Perk[] | (Deprecated) This property is no longer in use and will not include all types of perks. The Perk endpoint is the recommended method to lookup perks at a business. | |
perkville_url | string | The canonical URL of the business' home page in in Perkville | |
resource_uri | string | The url of this Business record in Perkville's API. | |
rewards_program_name | string | The name of the rewards program. This value is used when referring to the rewards program in emails an on the business' profile. | |
app_connection_message | string | A custom message displayed to customers explaining why they need to connect their Perkville account to the business' mobile app. |
POST
PATCH
DELETE
Business Staff
A perkville user that has been assigned a staff role at a business.
The Business Staff resource is filtered based on the user who owns the token making the request. Only business staff members at businesses the user making the request is a staff member at will be returned.
GET
GET /v2/staff/{STAFF_ID}/
Example
Example Request
curl https://api.perkville.com/v2/staff/1/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "staff_id": "1", "business": "/v2/businesses/4/", "created": "2015-06-25T19:19:25+00:00", "bill_payer": true, "resource_uri": "/v2/staff/1/", "staff_role": "ADMIN", "staff_description": "", "user": "/v2/users/263726" }
Restrictions
Required scopes:
- USER_CUSTOMER_INFO
Fields
Property Name | Type | Filterable | Description |
staff_id | string | The unique ID number given to the staff record. | |
business | Business | ✓ | The business to which the staff record belongs. |
created | datetime | The date and time the staff member was created. | |
bill_payer | boolean | ✓ | Is this staff member the billing responsible user at the associated business. |
staff_role | string | ✓ | The role in Perkville the staff member has been assigned. Options are 'ADMIN', 'EMPLOYEE', 'FRONT_DESK', 'EMAIL_ONLY', or 'SCAN_VOUCHER'. |
staff_description | string | In Perkville, a business can add a description for a staff member object. This field is the description a business gave to the staff member. | |
user | User | ✓ | The URI of the User associated with the staff record. (SUPPORTS RELATIONAL QUERIES) |
POST
PATCH
DELETE
Challenge
A "Challenge" is a Perkville client, and represents a single rewards program for a real world business.
Users can have a ChallengeConnection to a Challenge, which represents the customer relationship between the User and a Challenge at a Business.
Challenges have Challenge Requirements, which are the collection of rules defining how many times a user must earn a Perk before completing a requirement.
Challenges also have Challenge Rewards, which are distributed to users after completing the Challenge Requirements.
GET
GET /v2/challenges/{CHALLENGE_ID}/
Example
Example Request
curl https://api.perkville.com/v2/challenges/4/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "business": "/v2/businesses/2/", "challenge_id": 5, "description": "Good luck, and have fun!", "end_date": "2020-07-31", "fine_print": "", "home_locations": [], "incomplete_message": "You'll get it next time!", "ineligible_message": "Sorry, you do not meet the requirements for this challenge.", "join_message": "Welcome to the challenge! Good luck!", "locations": [ "/v2/locations/1/" ], "name": "Push Up Challenge", "resource_uri": "/v2/challenges/5/", "require_active_membership": false, "slug": "push-up-challenge", "start_date": "2020-06-21", "success_message": "Congratulations! You've completed the challenge!", "use_membership_start_date": false, "valid_customer_attributes": [] },
Restrictions
Required scopes:
- PUBLIC
Fields
Property Name | Type | Filterable | Description |
challenge_id | int | ✓ | The challenge ID |
business | Business | ✓ | The business to which the challenge belongs. |
name | string | ✓ | Name of the challenge |
slug | string | ✓ | A URL slug to be used to navigate to this challenge. Slug values are only required to be unique for each business. Be aware that if the bearer token user is authorized at more then one business, multiple records could be returned. In these cases it is advised to also use the `business` filter if you only want to get back one record. |
description | string | The long form user-facing description of this challenge. Usually this is used to give detailed information about the challenge. | |
fine_print | string | Contains any restrictions on participation in this challenge. | |
join_message | string | A message to display to the user when they join the challenge. | |
ineligible_message | string | A message to display to the user when they are ineligible to join the challenge. | |
success_message | string | A message to display to the user when they have successfully completed the challenge. | |
incomplete_message | string | A message to display to the user when they did not complete the challenge in time. | |
locations | Location[] | An array of Location resources, which are eligible transaction locations for this challenge. If there are no locations listed, transactions at all locations can count towards progress on this challenge. | |
home_locations | Location[] | An array of Location resources, which are eligible member home locations for this challenge. If there are no locations listed, this challenge is available to all locations. | |
start_date | date | The start date of this challenge. Can be blank. | |
end_date | date | The end date of this challenge. Can be blank. | |
use_membership_start_date | boolean | For businesses that sync membership information, this is an option that can be configured when creating a challenge that starts/ends the challenge based on their membership start date. | |
require_active_membership | boolean | For businesses that sync membership information, this is an option that can be configured when creating a challenge that restricts participation to members with active memberships. | |
resource_uri | string | The url of this Challenge record in Perkville's API. | |
valid_customer_attributes | Custom Attribute Value[] | Used when the business has chosen to restrict the customers who can participate in this Challenge by those who have been assigned at least one of the listed values. |
POST
PATCH
DELETE
Challenge Connection
The relationship between a User and a Challenge is a Challenge Connection.
GET
GET /v2/challenge-connections/{CHALLENGE_CONNECTION_ID}/
Example
Example Request
curl https://api.perkville.com/v2/challenge-connections/15/ -H "Authorization: Bearer accesstoken123abc"
Example Response
example_response: | { "business": "/v2/businesses/2/", "challenge": "/v2/challenges/5/", "completed": false, "completed_dt": null, "connection": "/v2/connections/3/", "created_dt": "2020-02-06T23:27:05.641334+00:00", "end_date": null, "join_dt": "2020-02-08T13:15:55.259384+00:00", "join_status": "ACTIVE", "last_mod_dt": "2020-02-08T13:15:55.259384+00:00", "resource_uri": "/v2/challenge-connections/15/", "start_date": null },
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_INFO
- USER_CUSTOMER_INFO
If USER_CUSTOMER_INFO is present, the only accessible records are those Challenge Connections which belong to the User associated with the access token.
If ADMIN_CUSTOMER_INFO is present, the only accessible records are those Challenge Connections which belong to the Business which the User associated with the access token is an ADMIN staff member. For example, if the User associated with the access token is an ADMIN staff member at Business 1, this will return all Challenge Connection who belong to Business 1.
Required Filters
GET requests to the challenge connection endpoint that do not specify a CHALLENGE_CONNECTION_ID are required to append either a business filter, user/email filter, connection filter, or any combination of these. Using an "IN" style query with the business filter is also not allowed with this resource.
Examples of VALID requests:
/v2/challenge-connections/55/ /v2/challenge-connections/?business=6 /v2/challenge-connections/?business=6&connection__user=1125 /v2/challenge-connections/?challenge=5&user__in=1123,1125 /v2/challenge-connections/?user=1125 /v2/challenge-connections/?user__in=1123,1125 /v2/challenge-connections/?email=api@perkville.com
Examples of INVALID requests:
/v2/challenge-connections/ /v2/challenge-connections/?business__in=5,6 /v2/challenge-connections/?business__in=6,7&user=1122 /v2/challenge-connections/?business__in=6,7&user__emails__email=api@perkville.com
Fields
Property Name | Type | Filterable | Description |
challenge | Challenge | ✓ | The uri of the challenge to which this connection belongs. |
connection | Connection | ✓ | The uri of the connection associated with this challenge. (SUPPORTS RELATIONAL QUERIES) |
business | Business | ✓ | The uri of the business to which this connection and challenge belongs. |
join_status | string | ✓ | Indicates if the user has agreed to participate in this challenge for this business. Values include "ACTIVE", "INACTIVE", and "PENDING". |
join_dt | datetime | The date on which this challenge connection joined the challenge, if applicable | |
completed | boolean | Indicates if this challenge connection has completed this challenge. | |
completed_dt | datetime | The date on which this challenge connection completed the challenge, if applicable | |
start_date | datetime | The start date for this specific challenge connection. Certain challenges will have this start date populated for specific users. | |
end_date | datetime | The end date for this specific challenge connection. Certain challenges will have this end date populated for specific users. | |
created_dt | datetime | The date on which this challenge connection was created | |
last_mod_dt | datetime | ✓ | The date on which this challenge connection was last modified |
POST
POST /v2/challenge-connections/
Example
Example Request
curl https://api.perkville.com/v2/challenge-connections/ -H "Authorization: Bearer accesstoken123abc" -H "Content-Type: application/json" -d '{"challenge": "/v2/challenges/5/", "join_status": "ACTIVE"}'
Example Response
{ "business": "/v2/businesses/2/", "challenge": "/v2/challenges/5/", "completed": false, "completed_dt": null, "connection": "/v2/connections/3/", "created_dt": "2020-02-06T23:27:05.641334+00:00", "end_date": null, "join_dt": "2020-02-08T13:15:55.259384+00:00", "join_status": "ACTIVE", "last_mod_dt": "2020-02-08T13:15:55.259384+00:00", "resource_uri": "/v2/challenge-connections/15/", "start_date": null }
Restrictions
Required Scopes
- USER_CUSTOMER_INFO
When creating a Challenge Connection, the following fields must always be present:
- Challenge URI
- Join Status
POSTing to this endpoint will add/update the join status of the user associated with the bearer token. If the join status is set to "ACTIVE", the user will be added to the challenge (if eligible). If the join status is set to "INACTIVE", the user will be opted out of the challenge if and only if they already have a connection record at the business. Users who are not part of the rewards program (do not have a connection) cannot preemptively opt out of a challenge.
Parameters
Property Name | Type | Description |
challenge | Challenge | The uri of the challenge you want to add the connection to. |
join_status | string | Indicates if the user has agreed to participate in this challenge for this business. Must be either "ACTIVE" or "INACTIVE". |
Returns
A 201 response with the JSON object of the created/updated Challenge Connection.
PATCH
PATCH /v2/challenge-connections/{CHALLENGE_CONNECTION_ID}/
Example
Example Request
curl --request PATCH https://api.perkville.com/v2/challenge-connections/15/ -H "Authorization: Bearer accesstoken123abc" -H "Content-Type: application/json" -d '{"join_status": "INACTIVE"}'
Example Response
{ "business": "/v2/businesses/2/", "challenge": "/v2/challenges/5/", "completed": false, "completed_dt": null, "connection": "/v2/connections/3/", "created_dt": "2020-02-06T23:27:05.641334+00:00", "end_date": "2020-07-06", "join_dt": null "join_status": "INACTIVE", "last_mod_dt": "2020-02-08T13:15:55.259384+00:00", "resource_uri": "/v2/challenge-connections/15/", "start_date": "2020-06-06" }
Restrictions
Required Scopes
- USER_CUSTOMER_INFO
When updating a Challenge Connection, the following fields must always be present:
- Join Status
If the join status is set to "ACTIVE", the user will join the challenge (if eligible). If the join status is set to "INACTIVE", the user will be opted out of the challenge.
Parameters
Property Name | Type | Description |
join_status | string | Indicates if the user has agreed to participate in this challenge for this business. Must be either "ACTIVE" or "INACTIVE". |
Returns
A 202 response with the JSON object of the updated Challenge Connection.
DELETE
Challenge Connection Requirement Summary
The relationship between a Challenge Connection and a Challenge Perk Requirement is a Challenge Connection Requirement Summary.
GET
GET /v2/challenge-connection-requirement-summaries/{CHALLENGE_CONNECTION_SUMMARY_ID}/
Example
Example Request
curl https://api.perkville.com/v2/challenge-connection-requirement-summaries/33/ -H "Authorization: Bearer accesstoken123abc"
Example Response
example_response: | { "challenge": "/v2/challenges/5/", "challenge_connection": "/v2/challenge-connections/15/", "challenge_perk_requirement": "/v2/challenge-requirements/7/", "completed_dt": null, "completed_requirement": false, "created_dt": "2020-02-06T23:27:05.641334+00:00", "earned_quantity": 6, "last_mod_dt": "2020-02-06T23:27:05.641334+00:00", "resource_uri": "/v2/challenge-connection-requirement-summaries/33/" },
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_INFO
- USER_CUSTOMER_INFO
If USER_CUSTOMER_INFO is present, the only accessible records are those Challenge Connection Summaries which belong to the User associated with the access token.
If ADMIN_CUSTOMER_INFO is present, the only accessible records are those Challenge Connections Summaries which belong to the Business which the User associated with the access token is an ADMIN staff member. For example, if the User associated with the access token is an ADMIN staff member at Business 1, this will return all Challenge Connection Summaries who belong to Business 1.
Required Filters
GET requests to the challenge connection summary endpoint that do not specify a CHALLENGE_CONNECTION_SUMMARY_ID are required to append either a challenge filter, challenge connection filter, challenge perk requirement filter, or any combination of these. Using an "IN" style query with the challenge filter is also not allowed with this resource.
Examples of VALID requests:
/v2/challenge-connection-requirement-summaries/55/ /v2/challenge-connection-requirement-summaries/?challenge=6 /v2/challenge-connection-requirement-summaries/?challenge=6&last_mod_dt__gte=2020-05-01 /v2/challenge-connection-requirement-summaries/?challenge=5&challenge_connection__in=1123,1125 /v2/challenge-connection-requirement-summaries/?challenge_connection=1125 /v2/challenge-connection-requirement-summaries/?challenge_connection__in=1123,1125 /v2/challenge-connection-requirement-summaries/?challenge_perk_requirement=24
Examples of INVALID requests:
/v2/challenge-connection-requirement-summaries/ /v2/challenge-connection-requirement-summaries/?challenge__in=5,6 /v2/challenge-connection-requirement-summaries/?challenge__in=6,7&challenge_connection=1122 /v2/challenge-connection-requirement-summaries/?challenge__in=6,7&user__emails__email=api@perkville.com
Fields
Property Name | Type | Filterable | Description |
challenge | Challenge | ✓ | The challenge to which this summary record applies. |
challenge_connection | ChallengeConnection | ✓ | The challenge connection to which this summary record applies. |
challenge_perk_requirement | ChallengePerkRequirement | ✓ | The challenge perk requirement to which this summary record applies. |
earned_quantity | int | The amount of times the User has earned the challenge perk requirement. | |
completed_requirement | boolean | Whether this user has completed the challenge perk requirement. Note, this value can be altered after the requirement is complete. Therefore, it may differ from the required quantity listed on the Challenge Perk Requirement | |
completed_dt | datetime | The date on which the challenge connection completed the challenge perk requirement, if applicable | |
created_dt | datetime | The date on which this summary record was created | |
last_mod_dt | datetime | ✓ | The date on which this summary record was last modified |
POST
PATCH
DELETE
Challenge Perk Requirement
A Challenge Perk Requirement is a rule defining how many times a user must earn a Perk before completing a requirement for a single Challenge.
These requirements are tracked through PROGRESS_ACTIVITY type Perks. Note: Multiple requirements can point to a single PROGRESS_ACTIVITY Perk. For instance, two different challenges have a requirement to earn a "Attend a class". These two Challenge Perk Requirements would point to the same PROGRESS_ACTIVITY perk.
GET
GET /v2/challenge-requirements/{CHALLENGE_PERK_REQUIREMENT_ID}/
Example
Example Request
curl https://api.perkville.com/v2/challenge-requirements/7/ -H "Authorization: Bearer accesstoken123abc"
Example Response
example_response: | { "business": "/v2/businesses/2/", "challenge": "/v2/challenges/5/", "challenge_perk_requirement_id": 7, "description": "Any pushup is a good pushup!", "detail_link": "", "display_order": null, "progress_perk": "/v2/perks/17/", "required_quantity": 50, "resource_uri": "/v2/challenge-requirements/7/", "title": "Do 50 pushups" },
Restrictions
Required scopes:
- PUBLIC
Required Filters
GET requests to the challenge perk requirement endpoint that do not specify a CHALLENGE_PERK_REQUIREMENT_ID are required to append a challenge or business filter. Using an "IN" style query with the business filter is also not allowed with this resource.
Fields
Property Name | Type | Filterable | Description |
challenge_perk_requirement_id | int | ✓ | The challenge perk requirement ID |
challenge | Challenge | ✓ | The challenge to which this requirement belongs. |
progress_perk | string | The Perk used to track this requirement. This is a special perk that does not alter a Connection's balance. It only contributes towards a User's progress for a Challenge Requirement. Please note, this progress perk could be connected to more than one Challenge Requirement. This is the Perk one should use when posting to the Transactions endpoint. | |
business | Business | ✓ | The uri of the business to which this requirement belongs. |
title | string | The display title for this requirement. This is customizable for this specific requirement for this specific challenge. Therefore, this title will differ from the connected progress_perk. | |
required_quantity | int | The amount of times the User must earn this requirement. | |
description | string | The long form user-facing description of this requirement. | |
detail_link | string | A URL providing more detail about this requirement. | |
display_order | string | The url of this Challenge record in Perkville's API. |
POST
PATCH
DELETE
Connection
The relationship between a User and a Business is a Connection. Together with User, it represents a customer.
The set of customers for a Business are the Users who have a Connection to that Business.
GET
GET /v2/connections/{CONNECTION_ID}/
Example
Example Request
curl https://api.perkville.com/v2/connections/3/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "business": "/v2/businesses/4/", "connection_id": 3, "external_cancel_dt": null, "external_join_dt": "2015-11-22T17:55:24+00:00", "external_membership_status": "ACTIVE", "external_membership_type": "Basic", "rewards_program_join_dt": "2016-03-02T13:33:11+00:00", "home_location": "/v2/locations/8/", "last_mod_dt": "2016-03-02T13:33:11+00:00", "last_transaction_dt": "2016-04-06T23:22:58+00:00", "last_visited_location": "/v2/locations/8/", "level": null, "lifetime_earned_points": 300, "point_balance": 14, "resource_uri": "/v2/connections/3/", "referral_offer_url": "https://www.perkville.com/biz/4/referral/261998/", "status": "ACTIVE", "user": "/v2/users/261998/", "vouchers": [] }
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_INFO
- USER_CUSTOMER_INFO
If USER_CUSTOMER_INFO is present, the only accessible records are those Connections which belong to the User associated with the access token.
If ADMIN_CUSTOMER_INFO is present, the only accessible records are those Connections which belong to the Business which the User associated with the access token is an ADMIN staff member. For example, if the User associated with the access token is an ADMIN staff member at Business 1, this will return all Connection who belong to Business 1.
Required Filters
GET requests to the connection endpoint that do not specify a CONNECTION_ID are required to append either a business filter, user filter, or both. Using an "IN" style query with the business filter is also not allowed with the connection resource.
Examples of VALID requests:
/v2/connections/55/ /v2/connections/?business=6 /v2/connections/?business=6&user=1125 /v2/connections/?business=6&user__in=1123,1125 /v2/connections/?user=1125 /v2/connections/?user__in=1123,1125 /v2/connections/?user__emails__email=api@perkville.com
Examples of INVALID requests:
/v2/connections/ /v2/connections/?business__in=5,6 /v2/connections/?business__in=6,7&user=1122 /v2/connections/?business__in=6,7&user__emails__email=api@perkville.com
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The business to which this connection is for; i.e., the given user is a customer at this business |
connection_id | int | The primary key of this Connection | |
external_cancel_dt | datetime | The date and time a user's membership status converted from "ACTIVE" to "INACTIVE" | |
external_join_dt | datetime | The date and time a user's membership became "ACTIVE" | |
rewards_program_join_dt | datetime | The date and time the user joined the business's rewards program. This field can be null if the user has not joined the rewards program. | |
external_membership_status | string | ✓ | Indicates the user's membership status at the business. Values include "ACTIVE", "INACTIVE", or null. |
external_membership_type | string | The user's membership type at the business | |
home_location | Location | ✓ | The user's home location at the business |
last_mod_dt | datetime | ✓ | The date and time that this record was last modified in UTC. Note that this datetime primarily applies to the "status" attribute and external membership information. For recently modified point balances, please use the Connection Balance resource. |
last_transaction_dt | datetime | The date and time of the customer's last transaction in UTC | |
last_visited_location | Location | The last location where this customer visited. | |
level | Level | The current level of the user. Can be null if the business is not using that feature or if the user has not earned enough points to be in any level. | |
lifetime_earned_points | int | The total amount of points the customer has earned at the business through Perkville | |
point_balance | int | The current balance of this customer | |
resource_uri | string | The url of this Connection record in Perkville's API. | |
referral_offer_url | string | The unique referral offer url to the business referred by this customer. | |
status | string | ✓ | Indicates if the user has accepted the rewards program for this business. Values include "ACTIVE", "INACTIVE", "PENDING", and "IMPORTED". |
user | User | ✓ | The user to which this connection belongs. (SUPPORTS RELATIONAL QUERIES) |
vouchers | Voucher[] | The list of vouchers for this business connection |
POST
PATCH
PATCH /v2/connections/{CONNECTION_ID}/
Example
Example Request
curl --request PATCH https://api.perkville.com/v2/connections/3/ -H "Authorization: Bearer accesstoken123abc" -H "Content-Type: application/json" -d '{ "status": "ACTIVE" }'
Example Response
{ "business": "/v2/businesses/4/", "connection_id": 3, "external_cancel_dt": null, "external_join_dt": "2015-11-22T17:55:24+00:00", "external_membership_status": "ACTIVE", "external_membership_type": "Basic", "rewards_program_join_dt": "2016-03-02T13:33:11+00:00", "home_location": "/v2/locations/6/", "last_mod_dt": "2017-03-22T23:32:33+00:00", "last_transaction_dt": "2016-04-06T23:22:58+00:00", "last_visited_location": "/v2/locations/8/", "level": null, "lifetime_earned_points": 300, "point_balance": 14, "resource_uri": "/v2/connections/3/", "referral_offer_url": "https://www.perkville.com/biz/4/referral/261998/", "status": "ACTIVE", "user": "/v2/users/261998/", "vouchers": [] }
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_INFO
- USER_CUSTOMER_INFO
If USER_CUSTOMER_INFO is present, you may only PATCH the status field for Connections belonging to the User associated with the access token.
If ADMIN_CUSTOMER_INFO is present, you may only PATCH external_cancel_dt, external_join_dt, external_home_location_id, external_membership_status, external_membership_type, and home_location for Connections belonging to the Business at which the User associated with the access token is an ADMIN staff member.
Parameters
Property Name | Type | Description |
external_cancel_dt | datetime | DEPRECATED - Please use External Member - This field is strongly suggested if setting the user's external_membership_status to INACTIVE. The date and time a user's membership status converted from "ACTIVE" to "INACTIVE". This will be converted to UTC, so we strongly suggest adding UTC offset or Z to the datetime. |
external_join_dt | datetime | DEPRECATED - Please use External Member - This field is strongly suggested if setting the user's external_membership_status to ACTIVE. The date and time a user's membership became "ACTIVE". This will be converted to UTC, so we strongly suggest adding UTC offset or Z to the datetime. |
external_membership_status | string | DEPRECATED - Please use External Member - Indicates the user's membership status at the business. Valid values are "ACTIVE" and "INACTIVE" ONLY. |
external_membership_type | string | DEPRECATED - Please use External Member - This is an OPTIONAL parameter. The user's membership type at the business |
external_home_location_id | string | DEPRECATED - Please use External Member - This is an OPTIONAL parameter. The external_location_id of the user's home Location. Include this or the home_location, but not both. |
home_location | Location | DEPRECATED - Please use External Member - This is an OPTIONAL parameter. The uri of the user's home Location. Include this or the external_home_location_id, but not both. |
status | string | Indicates if the user has accepted the rewards program for this business. Valid values are "ACTIVE" and "INACTIVE" ONLY. |
Returns
202 Accepted with a JSON object of the patched Connection.
DELETE
Connection Attribute
Records from this resource indicate that a custom attribute value has been assigned to a connection.
This endpoint provides the ability to view the attribute values associated with a business's customers, to add new ones, and to remove them.
GET
GET /v2/connection-attributes/{CONNECTION_ATTRIBUTE_ID}/
Example
Example Request
curl https://api.perkville.com/v2/connection-attributes/12/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "added_dt": "2020-02-04T22:26:19.283853+00:00", "connection": "/v2/connections/14940/", "custom_attribute_value": "/v2/custom-attribute-values/2/", "resource_uri": "/v2/connection-custom-attribute-values/12/" }
Restrictions
Required Scopes:
- At least one of these:
- USER_CUSTOMER_INFO
- ADMIN_CUSTOMER_INFO
- ADMIN_CUSTOMER_GRANT_POINTS
If USER_CUSTOMER_INFO is present, the only accessible records are those that reference a connection which belongs to the user associated with the access token.
If either of the ADMIN scopes are present, the accessible records will be those that reference connections belonging to a businesses of which the access token user is a staff.
Required Filters
GET requests to this endpoint that do not specify a CONNECTION_ATTRIBUTE_ID are required to use one of the valid filters for this resource.
Examples of VALID Requests
/v2/connection-attributes/25/ /v2/connection-attriibutes/?connection=1123 /v2/connection-attributes/?custom_attribute_value=2 /v2/connection-attributes/?connection=1123&custom_attribute_value=2
Fields
Property Name | Type | Filterable | Description |
connection | Connection | ✓ | The uri of the connection assigned an attribute value |
custom_attribute_value | Custom Attribute Value | ✓ | The uri of the Custom Attribute Value assigned to the connection |
added_dt | datetime | The datetime when the custom attribute value was assigned to the connection |
POST
POST /v2/connection-attributes/
Example
Example Request
curl https://api.perkville.com/v2/connection-attributes/ -H "Authorization: Bearer accesstoken123abc" -H "Content-Type: application/json" -d '{"connection": "/v2/connections/14999/", "custom_attribute_value": "/v2/custom-attribute-values/4/"}'
Example Response
{ "added_dt": "2020-02-06T15:18:10.891727+00:00", "connection": "/v2/connections/14999/", "custom_attribute_value": "/v2/custom-attribute-values/4/", "resource_uri": "/v2/connection-custom-attribute-values/5/" }
Restrictions
Required Scopes
- ADMIN_CUSTOMER_GRANT_POINTS
When creating a Connection Custom Attribute Value, the following fields must always be present:
- Connection URI
- Custom Attribute Value URI
If a record already exists that references both the connection and the custom attribute value, an "invalid_request_error" response with the status code 400 will be returned. The response body will also include an error with the code "pv_api_duplicate_connection_attribute".
Parameters
Property Name | Type | Description |
connection | Connection | The uri of the connection you want to assign an attribute value to |
custom_attribute_value | Custom Attribute Value | The uri of the Custom Attribute Value you want to assign to the connection |
Returns
A 201 response with the JSON object of the created Connection Custom Attribute Value.
PATCH
DELETE
DELETE /v2/connection-attributes/
Example
Example Request
curl -X DELETE https://api.perkville.com/v2/connection-attributes/12/ -H "Authorization: Bearer accesstoken123abc"
Restrictions
Required Scopes
- ADMIN_CUSTOMER_GRANT_POINTS
A CONNECTION_ATTRIBUTE_ID must always be used. Batch delete requests are not supported.
Returns
A 204 response with no content
Connection Balance
The point balance of a Connection. This endpoint provides the ability to fetch recently updated point balances for a given Business.
While the Connection endpoint includes point balance as a matter of convenience, you cannot filter for Connections who recently had their balances adjusted.
GET
GET /v2/connection-balances/{CONNECTION_BALANCE_ID}/
Example
Example Request
curl https://api.perkville.com/v2/connection-balances/5/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "business": "/v2/businesses/4/", "connection": "/v2/connections/3/", "last_biz_perk_title": "Check in", "last_mod_dt": "2016-03-02T13:33:11+00:00", "last_transaction_dt": "2016-03-02T13:33:10+00:00", "lifetime_earned_points": 300, "lifetime_spent_points": 286, "point_balance": 14, "resource_uri": "/v2/connection-balances/5/", "user": "/v2/users/261998/" }
Restrictions
Required scopes:
- PUBLIC
- ADMIN_CUSTOMER_INFO
If ADMIN_CUSTOMER_INFO is present, the only accessible records are those Connections which belong to the Business which the User associated with the access token is an ADMIN staff member. For example, if the User associated with the access token is an ADMIN staff member at Business 1, this will return all Connection who belong to Business 1.
Required Filters
GET requests to the connection endpoint that do not specify a CONNECTION_BALANCE_ID are required to append at least a connection filter, business filter, or user filter. Using an "IN" style query with the business filter is also not allowed with the connection balance resource.
Examples of VALID requests:
/v2/connection-balances/55/ /v2/connection-balances/?business=6 /v2/connection-balances/?business=6&last_mod_dt__gte=2019-01-01 /v2/connection-balances/?business=6&user__in=1123,1125 /v2/connection-balances/?user=1125 /v2/connection-balances/?user__in=1123,1125 /v2/connection-balances/?email=api@perkville.com /v2/connection-balances/?connection=3
Examples of INVALID requests:
/v2/connection-balances/ /v2/connection-balances/?business__in=5,6 /v2/connection-balances/?last_mod_dt__gte=2019-01-01
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The business to which this connection is for; i.e., the given user is a customer at this business |
connection | Connection | ✓ | The relationship between a User and a Business |
last_biz_perk_title | string | The name of the Perk for their latest transaction | |
last_mod_dt | datetime | ✓ | The date and time that this record was last modified in UTC. |
last_transaction_dt | datetime | The date and time of the customer's last transaction in UTC | |
lifetime_earned_points | int | The total amount of points the customer has earned at the business through Perkville | |
lifetime_spent_points | int | The total amount of points the customer has spent at the business through Perkville | |
point_balance | int | The current balance of this customer | |
resource_uri | string | The url of this Connection Balance record in Perkville's API. | |
user | User | ✓ | The user to which this connection belongs. (SUPPORTS RELATIONAL QUERIES) |
POST
PATCH
DELETE
Custom Attribute
This endpoint provides the ability to view the custom attributes created by businesses.
Business have to option to create any number of custom attributes for use in their rewards program. Custom Attribute instances describe what the attribute is called and other bits of customizable text related to that attribute. Custom Attribute instances do not include the possible values associated with an attribute. In order to get that information see the "Custom Attribute Value" resource.
GET
GET /v2/custom-attributes/{CUSTOM_ATTRIBUTE_ID}/
Example
Example Request
curl https://api.perkville.com/v2/custom-attributes/1/ -H "Authorizatiuon: Bearer accesstoken123abc"
Example Response
{ "business": "/v2/businesses/5/", "description": "My attribute description", "display_action": "", "display_name": "My custom attribute", "resource_uri": "/v2/custom-attributes/1/", "slug": "" }
Restrictions
Required Scopes:
- At least one of these:
- USER_CUSTOMER_INFO
- ADMIN_CUSTOMER_INFO
If USER_CUSTOMER_INFO is present, the only accessible records are those that reference a custom attribute value which has been assign to a connection associated with the access token user.
If ADMIN_CUSTOMER_INFO is present, the accessible records will be those that were created by one of the businesses where the access token user is a staff.
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The uri of the business that created the custom attribute. |
display_name | string | The name of the attribute as it appears when displayed to users. | |
display_action | string | (Optional) A business can choose to display the attribute on their profile. If so, the value in this field will be `DISPLAY_AS_BIZ_PROFILE_TAB`. | |
slug | string | ✓ | (Optional) A URL slug to be used if the business has chosen `DISPLAY_AS_BIZ_PROFILE_TAB` as a display action. Slug values are only required to be unique for each business. Be aware that if the bearer token user is authorized at more then one business, multiple records could be returned. In these cases it is advised to also use the `business` filter if you only want to get back one record. |
POST
PATCH
DELETE
Custom Attribute Value
This endpoint provides the ability to view the values associated with custom attributes.
Requests to this endpoint that do not specify a primary key, or use a filter, will return values for all custom attributes at all of the businesses authorized for the bearer token user. The best way to see only the values associated with a specific custom attribute is to use the custom_attribute
filter.
GET
GET /v2/custom-attribute-values/{CUSTOM_ATTRIBUTE_VALUE_ID}/
Example
Example Request
curl https://api.perkville.com/v2/custom-attribute-values/10/ -H "Authorizatiuon: Bearer accesstoken123abc"
Example Response
{ "custom_attribute": "/v2/custom-attributes/5/", "display_name": "My attribute value", "order": null, "resource_uri": "/v2/custom-attribute-values/10/" }
Restrictions
Required Scopes:
- At least one of these:
- USER_CUSTOMER_INFO
- ADMIN_CUSTOMER_INFO
If USER_CUSTOMER_INFO is present, the only accessible records are those that have been assigned to a connection of the user associated with the access token.
If ADMIN_CUSTOMER_INFO is present, the accessible records will be those that reference a custom attribute created by one of the businesses where the access token user is a staff.
Fields
Property Name | Type | Filterable | Description |
custom_attribute | Custom Attribute | ✓ | The uri of the custom attribute this value is for. |
display_name | string | The name of the value as it appears when displayed to users. | |
order | int | (Optional) Values for a custom attributes can arranged into a hierarchy using this field. |
POST
PATCH
DELETE
Email Tracking
Returns a list of emails sent from Perkville businesses associated with the API token used.
This endpoint can be filtered on most fields. The `type` field can be filtered on using the following values:>
Emails sent to business customers
- USER_WARM_REG_REQUEST
- Sent to a business customer prompting them to join a rewards program after receiving points for the first time.
- USER_WARM_REG_REQUEST_NO_POINTS
- Sent to a business customer prompting them to join a rewards program if a business does not allow users to earn points until they join Perkville.
- USER_EARN_ALERT
- Sent to a business customer who is actively connected to a business' rewards program after earning new points.
- USER_REDEEM_ALERT
- Sent to a business customer after they redeem for a perk.
- BONUS_REFERRAL_INFORM
- Email that is sent when a business customer refers a friend and the business has not set up a referral offer.
- REFERRAL_OFFER
- Email that is sent when a business customer refers a friend and the business has an active referral offer.
- WEEKLY_CUSTOMER_REPORT
- Sent to a business customer summarizing their transaction activity over the past week.
- CLAIMED_OFFER
- Sent to a customer after they claim an offer from a business.
- VOUCHER_EXPIRES
- Sent to a business customer alerting them that they have unused vouchers that will expire soon.
- CUSTOMER_INVITE
- Sent to users that have been invited to join a business' loyalty program by a staff member.
- USER_COLD_REG_REQUEST
- Email containing a registration link that is sent to users who join Perkville by signing up on our website.
- POINT_EXPIRATION_WARN
- Sent to a business customer alerting them that they have points that will expire soon.
- CHALLENGE_INVITE
- Sent to a business customer inviting them to join a business' challenge.
- CHALLENGE_PROGRESS_UPDATE
- Sent to a business customer who is actively connected to a challenge after earning progress.
- CHALLENGE_COMPLETE
- Sent to a business customer who is actively connected to a challenge after completing the challenge.
Emails sent to business staff
- BUSINESS_DAILY_STATS
- Sent to business staff summarizing the activity at their business over the past day.
- WEEKLY_BUSINESS_REPORT
- Email sent to business admins summarizing their business' activity over the past week.
- MONTHLY_BUSINESS_REPORT
- Email sent to business admins summarizing their business' activity over the past month.
- BUSINESS_ADD_EMPLOYEE_INFORM
- Sent to a user when they are added as a staff member at a business.
- BUSINESS_LIVE_ALERT
- Sent to business admins when their business first goes live on Perkville.
- OBLIGATION
- Sent to business admins and employees when a customer claims an offer or redeems a perk.
- NOTIFY_LIMIT_EXCEEDED
- Sent to a business admin when a batch process fails because it attempted to upload too many records.
- BATCH_UPLOAD_REPORT
- Sent to a business admin after a batch process has successfully been completed.
- COMPLETED_REFERRAL_ADMIN_INFORM
- Sent to a business admin after a new customer has been successfully referred to their business.
- BIZ_COUPON_REMINDER
- For businesses that have uploaded custom coupon codes, this email is sent to staff when a location is running low.
- INVITE_BATCH_UPLOAD_REPORT
- Sent to a business admin after they have successfully uploaded a list of user's to be invited to their rewards program.
- BUSINESS_OVERAGE_WARN
- Sent to a business admin alerting them that they have exceeded the maximum number of transactions that their plan allows
Emails that may be sent to either staff or customers
- USER_CONFIRM_EMAIL_REQUEST
- Sent to users registering via our website or changing their primary email address.
- USER_MERGE_REQUEST
- A confirmation email sent as part of the user account merge process.
- USER_MERGE_OK
- Sent to a user after they have successfully merged two accounts.
Legacy - These emails are no longer used
- USER_EARN_WAITING_ALERT
- BUSINESS_WELCOME
- GET_STARTED_REPORT
- REFERRAL_PROMPT
- API_REGISTRATION_BONUS
- MARKETPLACE_ONLY_CONFIRM_EMAIL
- MARKETPLACE_ONLY_GET_STARTED
GET
GET /v2/email-tracking/{EMAIL_TRACKING_ID}/
Example
Example Request
curl https://api.perkville.com/v2/email-tracking/59/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "business_id": 1832, "resource_uri": "/v2/email-tracking/59/", "sent_dt": "2016-11-20T17:53:25+00:00", "type": "USER_EARN_ALERT", "user_email": "edward_test@perkville.com", "user_id": 263727 }
Restrictions
Required scopes:
- ADMIN_CUSTOMER_INFO
Fields
Property Name | Type | Filterable | Description |
business_id | integer | ✓ | The primary key of the business associated with this email. |
location_id | integer | The primary key of the location associated with this email. This field can be null if an email is not associated with any location in particular. | |
resource_uri | string | The url of this record in Perkville's API. | |
sent_dt | datetime | ✓ | The date and time this email was sent. |
type | string | ✓ | The type of email that was sent. |
user_email | string | ✓ | The address the email was sent to. |
user_id | integer | ✓ | The primary key of the user the email was sent to. |
POST
PATCH
DELETE
External Location
External Locations are used to associate a Perkville Location with an ID in another system. The combination of external_system_id and external_location_id is unique system-wide.
A single Perkville location can have multiple External Locations.
The purpose of this resource is to allow API clients to determine which Perkville Location corresponds to a location in another system.
GET
GET /v2/external-locations/{EXTERNAL_LOCATION_IDENTIFIER_ID}/
Example
Example Request
curl https://api.perkville.com/v2/external-locations/1/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "id": "1", "external_system_id": "ABC_FITNESS", "external_location_id": "0000", "location": "/v2/locations/5/" }
Restrictions
Required scopes:
- PUBLIC
Querystring Parameters
Name | Type | Required | Description |
external_system_id | string | ✓ | The unique name given to the External System. |
external_location_id | string | ✓ | The ID of the location in the External System. |
Fields
Property Name | Type | Filterable | Description |
id | string | The unique ID given to the External Location. | |
external_system_id | string | The unique name given to the External System. | |
external_location_id | string | The ID of the location in the External System. | |
location | Location | The Location to which this External Location belongs. |
POST
PATCH
DELETE
External Member
Fetch, update, or create external membership details for a user at a business.
Required Filters
GET requests to the external member endpoint that do not specify a EXTERNAL_MEMBER_IDENTIFIER_ID are required to append either a business filter, user filter, or both. Using an "IN" style query with the business filter is also not allowed on this resource. With the above conditions met, you may also filter on external_system_id, and, more specifically, external_member_id.
Examples of VALID requests:
/v2/external-members/55/ /v2/external-members/?business=6 /v2/external-members/?business=6&user=1125 /v2/external-members/?business=6&user__in=1123,1125 /v2/external-members/?user=1125 /v2/external-members/?user__in=1123,1125 /v2/external-members/?user__emails__email=api@perkville.com /v2/external-members/?business=6&external_system_id=EXAMPLE_SOFTWARE /v2/external-members/?business=6&external_system_id=EXAMPLE_SOFTWARE&external_member_id=1111111
Examples of INVALID requests:
/v2/external-members/ /v2/external-members/?business__in=5,6 /v2/external-members/?business__in=6,7&user=1122 /v2/external-members/?business__in=6,7&user__emails__email=api@perkville.com /v2/external-members/?external_member_id=1111111 /v2/external-members/?&external_system_id=EXAMPLE_SOFTWARE&external_member_id=1111111
GET
GET /v2/external-members/{EXTERNAL_MEMBER_IDENTIFIER_ID}/
Example
Example Request
curl https://api.perkville.com/v2/external-members/3/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "business": "/v2/businesses/2/", "connection": "/v2/connections/1/", "created_dt": "2019-04-01T23:16:47.266014+00:00", "external_cancel_dt": null, "external_join_dt": "2018-05-02T12:35:00+00:00", "external_member_id": "1111111", "external_membership_status": null, "external_membership_type": null, "external_system_id": "EXAMPLE_SOFTWARE", "home_location": "/v2/locations/2/", "id": "3", "last_mod_dt": "2019-04-01T23:16:47.266667+00:00", "resource_uri": "/v2/external-members/3/", "user": "/v2/users/2/" }
Restrictions
Required scopes:
- ADMIN_CUSTOMER_INFO
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The business to which this external member belongs. |
connection | Connection | The relationship between a User and a Business | |
user | User | ✓ | The user to which this external member belongs. (SUPPORTS RELATIONAL QUERIES) |
resource_uri | string | The url of this record in Perkville's API. | |
external_system_id | string | ✓ | A unique identifier representing the external system from which this member came. |
external_member_id | string | ✓ | The external identifier for this membership record. When filtering on this attribute, external_system_id is REQUIRED |
external_membership_type | string | The external member's membership type | |
external_membership_status | string | The external member's membership status. Values include "ACTIVE", "INACTIVE", or null. | |
home_location | Location | The external member's home location | |
external_cancel_dt | datetime | The date and time a user's membership status converted from "ACTIVE" to "INACTIVE" | |
external_join_dt | datetime | The date and time a user's membership became "ACTIVE" |
POST
POST /v2/external-members/
Example
Example Request
curl https://api.perkville.com/v2/external-members/ -H "Authorization: Bearer accesstoken123abc" -d '{"business": "/v2/businesses/1/", "home_location": "/v2/locations/2/", "external_member_id": "1111111", "external_system_id": "EXAMPLE_SOFTWARE", "user_email": "john.doe@example.org", "external_join_dt": "2018-05-02 12:35:00"}'
Example Response
{ "business": "/v2/businesses/2/", "connection": "/v2/connections/1/", "created_dt": "2019-04-01T23:16:47.266014+00:00", "external_cancel_dt": null, "external_join_dt": "2018-05-02T12:35:00+00:00", "external_member_id": "1111111", "external_membership_status": null, "external_membership_type": null, "external_system_id": "EXAMPLE_SOFTWARE", "home_location": "/v2/locations/2/", "id": "3", "last_mod_dt": "2019-04-01T23:16:47.266667+00:00", "resource_uri": "/v2/external-members/3/", "user": "/v2/users/2/" }
Restrictions
Required scopes:
- ADMIN_CUSTOMER_INFO
Parameters
Property Name | Type | Description |
business | Business | The business to which this external member belongs. |
user_email | string | The email of the user to which this external member belongs. |
external_member_id | string | The external identifier for this membership record |
external_system_id | string | A unique identifier representing the external system from which this member came. |
external_membership_type | string | OPTIONAL. The external member's membership type |
external_membership_status | string | OPTIONAL. The external member's membership status. Values include "ACTIVE", "INACTIVE", or null. |
home_location | Location | OPTIONAL. The URI of the external member's home location. Include this OR the "external_home_location_id" parameter, but not both. |
external_home_location_id | string | OPTIONAL. The external_location_id of the Location you'd like to use for this external member's home location. Include this OR the "home_location" parameter, but not both. |
external_cancel_dt | datetime | OPTIONAL. The date and time a user's membership status converted from "ACTIVE" to "INACTIVE" |
external_join_dt | datetime | OPTIONAL. The date and time a user's membership became "ACTIVE" |
birthday | date | OPTIONAL. The user's birthday as "YYYY-MM-DD". If the user already exists, and does not have a birthday on file, we will update the user with the provided birthday. |
first_name | string | OPTIONAL. The user's first name. If the user already exists, and does not have a first name on file, we will update the user with the provided first name. |
last_name | string | OPTIONAL. The user's last name. If the user already exists, and does not have a last name on file, we will update the user with the provided last name. |
can_receive_emails | boolean | Indicates if we should send any emails to this user. Defaults to true if nothing is passed in. Please note that this parameter only applies to newly created users. If the user/email already exists, this parameter will be ignored. |
Returns
A 201 response with a JSON object of the created External Member if successful.
PATCH
PATCH /v2/external-members/{EXTERNAL_MEMBER_IDENTIFIER_ID}/
Example
Example Request
curl https://api.perkville.com/v2/external-members/3/ -H "Authorization: Bearer accesstoken123abc" -d '{"home_location": "/v2/locations/1/", "external_membership_type": "NEW_TYPE", "external_membership_status": "ACTIVE"}'
Example Response
{ "business": "/v2/businesses/2/", "connection": "/v2/connections/1/", "created_dt": "2019-04-01T23:16:47.266014+00:00", "external_cancel_dt": null, "external_join_dt": "2018-05-02T12:35:00+00:00", "external_member_id": "1111111", "external_membership_status": "ACTIVE", "external_membership_type": "NEW_TYPE", "external_system_id": "EXAMPLE_SOFTWARE", "home_location": "/v2/locations/1/", "id": "3", "last_mod_dt": "2019-04-01T23:21:47.266667+00:00", "resource_uri": "/v2/external-members/3/", "user": "/v2/users/2/" }
Restrictions
Required scopes:
- ADMIN_CUSTOMER_INFO
Parameters
Property Name | Type | Description |
external_membership_type | string | The external member's membership type |
external_membership_status | string | The external member's membership status. Values include "ACTIVE", "INACTIVE", or null. |
home_location | Location | The external member's home location |
external_home_location_id | string | The external_location_id of the Location you'd like to use for this external member's home location. Include this OR the "home_location" parameter, but not both. |
external_cancel_dt | datetime | The date and time a user's membership status converted from "ACTIVE" to "INACTIVE" |
external_join_dt | datetime | The date and time a user's membership became "ACTIVE" |
birthday | date | OPTIONAL. The user's birthday as "YYYY-MM-DD". If the user already exists, and does not have a birthday on file, we will update the user with the provided birthday. |
first_name | string | OPTIONAL. The user's first name. If the user already exists, and does not have a first name on file, we will update the user with the provided first name. |
last_name | string | OPTIONAL. The user's last name. If the user already exists, and does not have a last name on file, we will update the user with the provided last name. |
Returns
A 201 response with a JSON object of the updated External Member if successful.
DELETE
Frequency Bonus Perk
A Frequency Bonus Perk is awarded when users earn a qualifying perk (defined by `qualifying_perks`) a certain number of times (defined by `required_to_earn`) within a particular period (defined by `frequency`).
GET
GET /v2/frequency-bonus-perk/{FREQUENCY_BONUS_PERK_ID}/
Example
Example Request
curl https://api.perkville.com/v2/frequency-bonus-perk/8/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "business": "/v2/businesses/25/", "frequency": "WEEKLY", "frequency_bonus_perk_id": 8, "qualifying_perks": [ "/v2/perks/480/" ], "required_to_earn": 3, "resource_uri": "/v2/frequency-bonus-perk/8/", "reward": "/v2/perks/742/" }
Restrictions
Required scopes:
- PUBLIC
Fields
Property Name | Type | Filterable | Description |
frequency_bonus_perk_id | integer | ✓ | The ID of this record |
business | Business | ✓ | The business that this bonus belongs to. |
qualifying_perks | Perk[] | ✓ | The list of perks which count towards this frequency bonus |
reward | Perk | ✓ | The reward given to the user after earning the requisite number of qualifying perks |
required_to_earn | integer | ✓ | The number of times that a user must earn one of the qualifying perks before receiving the reward |
frequency | string | Options are WEEKLY, MONTHLY, or FROM_DATE, indicates the time window during which users can accumulate the requisite number of earning events |
POST
PATCH
DELETE
Frequency Bonus Progress
Returns a list of users and their progress towards each frequency bonus perk. Important notes:
- Records will be present ONLY when a user has earned at least ONCE in the current time period. e.g., if a business has just one frequency bonus perk set up, for "3 Check-Ins per week", and user 1451243 has NOT earned any Check-Ins this week, then the query "GET /v2/frequency-bonus-progress/?user=1451243" would return NO records
- When making a request with the ADMIN_CUSTOMER_INFO scope, ensure that your user is a staff member with access to ALL locations at the business. We deliberate exclude records for staff members who are NOT authorized for all locations at a business.
GET
GET /v2/frequency-bonus-progress/{FREQUENCY_BONUS_PROGRESS_ID}/
Example
Example Request
curl https://api.perkville.com/v2/frequency-bonus-progress/19/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "business": "/v2/businesses/25/", "frequency_bonus_perk": "/v2/frequency-bonus-perk/8/", "frequency_bonus_progress_id": 19, "has_earned_bonus": false, "progress_count": 1, "resource_uri": "/v2/frequency-bonus-progress/19/", "user": "/v2/users/263726/" }
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_INFO
- USER_CUSTOMER_INFO
Fields
Property Name | Type | Filterable | Description |
frequency_bonus_progress_id | integer | ✓ | The ID of this record |
business | Business | ✓ | The business that this promotion belongs to. |
user | User | ✓ | The user which has had some progress towards this frequency bonus perk. (SUPPORTS RELATIONAL QUERIES) |
frequency_bonus_perk | FrequencyBonusPerk | ✓ | The perk which the user is progressing towards completing |
progress_count | integer | The number of times the user has earned the requisite perks | |
has_earned_bonus | boolean | Indicates if the user has earned this bonus |
POST
PATCH
DELETE
Level
Businesses can incorporate the idea of levels into their loyalty program. Once the Levels features has been activated, Perks can be restricted so that only users who have obtained a specified level can redeem them. Users can reach different levels by earning the amount of points set as the level's point_floor.
GET
GET /v2/levels/{level_id}/
Example
Example Request
curl https://api.perkville.com/v2/levels/2/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "badge_url": "https://example.perkville.com/images/1832/levels/2/badge/20170331164340.png", "business": "/v2/businesses/1832/", "level_id": 2, "name": "Silver", "point_floor": 750, "resource_uri": "/v2/levels/2/" }
Restrictions
Required scopes:
- PUBLIC
Fields
Property Name | Type | Filterable | Description |
level_id | integer | ✓ | The Level ID |
business | Business | ✓ | The Business associated with this level |
name | string | The name of the level | |
point_floor | integer | The amount of points a customer must earn to reach this level | |
badge_url | string | URL of the badge image associated with this level |
POST
PATCH
DELETE
Location
A Location is a physical place at which a Business resides.
GET
GET /v2/locations/{LOCATION_ID}/
Example
Example Request
curl https://api.perkville.com/v2/locations/1/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "address_1": "123 Main St.", "address_2": "", "business": "/v2/businesses/4/", "city": "San Francisco", "country_code": "us", "external_location_id": "AD123F", "latitude": "37.7833", "location_id": 1, "longitude": "122.4167", "name": "SF Shoppe", "postal_code": "94102", "resource_uri": "/v2/locations/1/", "state": "CA" }
Restrictions
Required scopes:
- PUBLIC
Fields
Property Name | Type | Filterable | Description |
address_1 | string | First line of this Location's physical address | |
address_2 | string | Second line of this Location's physical address | |
business | Business | ✓ | The Business to which this Location belongs |
city | string | The city where this Location resides | |
country_code | string | ✓ | The country code (e.g., "us" for the USA) |
external_location_id | string | ✓ | The external location ID, often used to associate a location with an ID in another system. |
latitude | string | The exact latitude of this location's physical address. | |
location_id | int | ✓ | The Perkville ID of this location |
longitude | string | The exact longitude of this location's physical address | |
name | string | The title of this location | |
postal_code | string | ✓ | The ZIP/postal code of this location |
state | string | The state code of this location (e.g., CA for California; Often this field used for provinces and similiar political entities.) |
POST
POST /v2/locations/
Example
Example Request
curl https://api.perkville.com/v2/locations/ -H "Authorization: Bearer accesstoken123abc" -H "Content-Type: application/json" -d '{ "address_1": "123 Main St.", "address_2": "", "business": "/v2/businesses/4/", "city": "Perkville", "country_code": "us", "external_location_id": "AD123F", "name": "POST Location", "postal_code": "94102", "state": "CA"}'
Example Response
201 Created { "address_1": "123 Main St.", "address_2": "", "business": "/v2/businesses/4/", "city": "Perkville", "country_code": "us", "external_location_id": "AD123F", "latitude": "37.7833", "location_id": 1, "longitude": "122.4167", "name": "POST Location", "postal_code": "94102", "resource_uri": "/v2/locations/1/", "state": "CA" }
Restrictions
Required scopes:
- ADMIN_LOCATION
Parameters
Property Name | Type | Description |
address_1 | string | First line of this Location's physical address |
address_2 | string | Second line of this Location's physical address |
business | Business | The Business to which this Location belongs |
city | string | The city where this Location resides |
country_code | string | The country code (e.g., "us" for the USA) |
external_location_id | string | An unique external location ID, often used to associate a location with an ID in another system. |
name | string | The title of this location |
postal_code | string | The ZIP/postal code of this location |
state | string | The state code of this location (e.g., CA for California; Often this field used for provinces and similiar political entities.) |
Returns
A 201 Created response with the newly created Location, as JSON
PATCH
PATCH /v2/locations/{LOCATION_ID}/
Example
Example Request
curl --request PATCH https://api.perkville.com/v2/locations/1/ -H "Authorization: Bearer accesstoken123abc" -H "Content-Type: application/json" -d '{ "name": "A new location name"}'
Example Response
202 Accepted { "address_1": "123 Main St.", "address_2": "", "business": "/v2/businesses/4/", "city": "Perkville", "country_code": "us", "external_location_id": "AD123F", "latitude": "37.7833", "location_id": 1, "longitude": "122.4167", "name": "A new location name", "postal_code": "94102", "resource_uri": "/v2/locations/1/", "state": "CA" }
Restrictions
Required scopes:
- ADMIN_LOCATION
Parameters
Property Name | Type | Description |
address_1 | string | First line of this Location's physical address |
address_2 | string | Second line of this Location's physical address |
business | Business | The Business to which this Location belongs |
city | string | The city where this Location resides |
country_code | string | The country code (e.g., "us" for the USA) |
external_location_id | string | An unique external location ID, often used to associate a location with an ID in another system. |
name | string | The title of this location |
postal_code | string | The ZIP/postal code of this location |
state | string | The state code of this location (e.g., CA for California; Often this field used for provinces and similiar political entities.) |
Returns
202 Accepted response with the updated Location, as JSON
DELETE
Perk
A Perk is a rewards rule for a Business, and are organized into two classifications: redemption or earning.
An earning Perk is a rule for how many points a customer earns for doing a particular thing, such as attending a one-on-one workout session, or spending $1.
A redeeming Perk is a rule for how many points a customer must spend to earn a reward. For example, spend 100 points and get a free $10 off coupon.
GET
GET /v2/perks/{PERK_ID}/
Example
Example Request
curl https://api.perkville.com/v2/perks/5/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "admin_flagged_as_invisible_to_customers": false, "business": "/v2/businesses/4/", "category": null, "classification": "REDEEM", "description": "We love our customers! Bring in this voucher for $10 off any purchase!", "end_date": null, "eligible_at_all_locations": true, "external_coupon_code": null, "external_reward_url": null, "fine_print": null, "initial_voucher_status": "UNUSED", "must_redeem_at_home_location": false, "perk_id": 5, "picture_card": null, "points": 100, "redemption_instructions": "Print or show on phone", "redemption_limit_count": null, "redemption_limit_interval": null, "redemption_limit_interval_count": null, "resource_uri": "/v2/perks/5/", "required_level": null, "start_date": null, "title": "$10 Off Any Purchase", "type": "STANDARD", "valid_customer_attributes": [] }
Restrictions
Required scopes:
- PUBLIC
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The business ID |
perk_id | int | The perk ID | |
status | string | Either 'ACTIVE' or 'INACTIVE'. If INACTIVE, the perk will no longer be eligible for earning or redeeming. | |
classification | string | ✓ | Either "EARN" or "REDEEM", indicating if this rule is for receiving points or for spending them. |
description | string | The long form user-facing description of this rule. Usually this is used to give detailed information about the Perk. | |
eligible_at_all_locations | boolean | Indicates if this rule applies to all locations. Note that right now, only REDEEM perks or EARN perks with a type of TIME_BONUS, FREQUENCY_BONUS, or DATE_RANGE_BONUS can specify eligible locations. | |
eligible_locations | Location[] | These are the locations at which this Perk is eligible. Note that if eligible_at_all_locations is True, then eligible_locations won't be included. | |
admin_flagged_as_invisible_to_customers | boolean | ✓ | Indicates if this perk is shown on the public facing rewards program. Transactions can still be created for these perks. Defaults to false. |
points | int | The number of points that this rule is worth | |
title | string | The short title of this Perk | |
type | string | This is a special field which indicates how the Perk is used. Options include 'STANDARD', 'POINT_ADJUSTMENT', 'BIRTHDAY', 'CHECKIN', 'COUPON', 'REFERRAL', 'REGISTRATION', 'TWITTER_POST', 'VISITOR', 'TIME_BONUS', 'FREQUENCY_BONUS', 'DATE_RANGE_BONUS', 'EXTERNAL_REWARD', 'PROGRESS_ACTIVITY'. | |
external_coupon_code | string | The business' internal identifier for this perk. Businesses typically use it instead of the voucher code when representing perkville vouchers in third party systems. | |
completes_referral | boolean | When this field is true, when a customer earns this perk, if that customer has an open referral where he or she is the one who was referred, that referral should be completed. This field may only be True for standard EARN type perks. | |
must_redeem_at_home_location | boolean | For businesses that sync membership information, this is an option that can be configured when creating a perk that requires users to redeem at their home location. | |
redemption_limit_interval | string | One of the following - 'NO_REDEMPTION_LIMIT', 'DAY', 'MONTH', 'YEAR', 'ALL_TIME'. Together with redemption_limit_interval_count and redemption_limit_count, this indicates how many times this perk can be redeemed within the interval. | |
redemption_limit_count | int | Populated if redemption_limit_interval is anything other than 'NO_REDEMPTION_LIMIT', and indicates how many times the perk can be redeemed in the given span of time. If the rule is that this can be redeemed "2 times in 10 Days", 2 is the redemption_limit_count. | |
redemption_limit_interval_count | int | Populated if redemption_limit_interval is 'DAY', 'MONTH' or 'YEAR', and indicates the span of time with which the redemption limit applies. If the rule is that this can be redeemed "2 times in 10 Days", 10 is the redemption_limit_interval_count. | |
required_level | Level | Indicates the minimum level, based on point_floor, that a user must unlock before they can redeem this perk. Use the Connection endpoint to determine a user's level at a business. | |
category | PerkCategory | The category of the perk, as defined by the business. | |
start_date | date | Populated if the perk's available start date has been set. | |
end_date | date | Populated if the perk's available end date has been set. | |
picture_card | string | If this perk has a photo, the URL of the photo is available in this attribute. | |
fine_print | string | Any specific rules that applies to the perk | |
external_reward_url | string | A URL to a third party reward provider | |
initial_voucher_status | string | The status of the voucher the customer receives when they redeem this perk. The options are UNUSED, USED, and ISSUED. | |
redemption_instructions | string | This text will be displayed on the voucher the customer receives when they redeem this perk. | |
valid_customer_attributes | Custom Attribute Value[] | Used when the business has chosen to restrict the customers who can transact with this perk by those who have been assigned at least one of the listed values. |
POST
POST /v2/perks/
Example
Example Request
curl https://api.perkville.com/v2/perks/ -H "Authorization: Bearer ryYMKAkopdwNb82FJTmxJ31L7T6K8z" -H "Content-Type: application/json" -d '{ "business": "/v2/businesses/4/", "classification": "REDEEM", "description": "Get 20% off any item in our gift shop!", "eligible_locations": [ "/v2/locations/35/" ], "points": 100, "title": "20% Off Coupon" }'
Example Response
201 Created { "admin_flagged_as_invisible_to_customers": false, "business": "/v2/businesses/4/", "category": null, "classification": "REDEEM", "description": "Get 20% off any item in our gift shop!", "eligible_at_all_locations": false, "eligible_locations": [ "/v2/locations/35/" ], "external_coupon_code": null, "fine_print": "Only valid for non-discounted items", "initial_voucher_status": "UNUSED", "perk_id": 6, "points": 100, "redemption_instructions": "Print or show on phone", "resource_uri": "/v2/perks/6/", "title": "20% Off Coupon", "type": "STANDARD", "picture_card": null, "valid_customer_attributes": [] }
Restrictions
Required scopes:
- ADMIN_PERK
Only STANDARD type perks can be created via the API at this time.
Parameters
Property Name | Type | Description |
business | Business | The business ID the perk belongs to. |
status | string | Either 'ACTIVE' or 'INACTIVE'. If INACTIVE, the perk will no longer be eligible for earning or redeeming. |
classification | string | The type of perk to be created. This can either be 'EARN' or 'REDEEM'. An 'EARN' perk is an earning rule that you can set up to give points to a business' customers. A 'REDEEM' perk is a redemption rule that describes what a customer can get and how many points they need to spend to get it. |
description | string | A detailed description of the Perk being offered. |
eligible_at_all_locations | boolean | If True, this perk is available at all of the business locations. Else, it's only available at the locations specified in the eligible_locations field. |
eligible_locations | Location[] | If eligible_at_all_locations is False, this field describes which locations the perk is associated with. |
external_coupon_code | string | The business' internal identifier for this perk. Businesses typically use it instead of the voucher code when representing perkville vouchers in third party systems. |
points | int | The point amount that can be earned for achieving this perk, or subtracted from the user's account for redeeming this perk. |
title | string | The name of the perk being offered. |
completes_referral | boolean | When this field is true, when a customer earns this perk, if that customer has an open referral where he or she is the one who was referred, that referral should be completed. This field may only be True for standard EARN type perks. This optional field defaults to True for EARN type perks, and is always False for REDEEM type perks. |
fine_print | string | Any specific rules that applies to the perk |
admin_flagged_as_invisible_to_customers | boolean | This is an OPTIONAL parameter. Indicates if this perk is shown on the public facing rewards program. Transactions can still be created for these perks. Defaults to false. |
initial_voucher_status | string | (Optional) Defaults to UNUSED. The status of the voucher the customer receives when they redeem this perk. The options are UNUSED, USED, and ISSUED. |
redemption_instructions | string | (Optional) Defaults to "Print or show on phone". This text will be displayed on the voucher the customer receives when they redeem this perk. |
Returns
201 Created response, with the newly-created Perk in the response body, as JSON
PATCH
PATCH /v2/perks/{PERK_ID}/
Example
Example Request
curl --request PATCH https://api.perkville.com/v2/perks/5/ -H "Authorization: Bearer ryYMKAkopdwNb82FJTmxJ31L7T6K8z" -H "Content-Type: application/json" -d '{ "title": "$20 Off Any Purchase", "points": 150 }'
Example Response
{ "admin_flagged_as_invisible_to_customers": false, "business": "/v2/businesses/4/", "category": null, "classification": "REDEEM", "description": "We love our customers! Bring in this voucher for $10 off any purchase!", "eligible_at_all_locations": true, "external_coupon_code": null, "initial_voucher_status": "UNUSED", "perk_id": 5, "points": 100, "redemption_instructions": "Print or show on phone", "resource_uri": "/v2/perks/5/", "title": "$10 Off Any Purchase", "type": "STANDARD", "picture_card": null, "valid_customer_attributes": [] }
Restrictions
Required scopes:
- ADMIN_PERK
Parameters
Property Name | Type | Description |
status | string | Either 'ACTIVE' or 'INACTIVE'. If INACTIVE, the perk will no longer be eligible for earning or redeeming. |
title | string | The name of the perk being offered. |
description | string | A detailed description of the Perk being offered. |
points | int | The point amount that can be earned for achieving this perk, or subtracted from the user's account for redeeming this perk. |
eligible_at_all_locations | boolean | If True, this perk is available at all of the business locations. Else, it's only available at the locations specified in the eligible_locations field. |
eligible_locations | Location[] array | If eligible_at_all_locations is False, this field describes which locations the perk is associated with. |
external_coupon_code | string | The business' internal identifier for this perk. Businesses typically use it instead of the voucher code when representing perkville vouchers in third party systems. |
completes_referral | boolean | When this field is true, when a customer earns this perk, if that customer has an open referral where he or she is the one who was referred, that referral should be completed. This field may only be True for standard EARN type perks. |
fine_print | string | Any specific rules that applies to the perk |
admin_flagged_as_invisible_to_customers | boolean | This is an OPTIONAL parameter. Indicates if this perk is shown on the public facing rewards program. Transactions can still be created for these perks. Defaults to false. |
initial_voucher_status | string | (Optional) The status of the voucher the customer receives when they redeem this perk. The options are UNUSED, USED, and ISSUED. |
redemption_instructions | string | (Optional) This text will be displayed on the voucher the customer receives when they redeem this perk. |
Returns
202 Accepted with a JSON object of the patched Perk
DELETE
Perk Category
A Perk Category is a grouping of Perks, which can be used to organize Perks for display purposes.
GET
GET /v2/perk-categories/{PERK_CATEGORY_ID}/
Example
Example Request
curl https://api.perkville.com/v2/perk-categories/1/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "category_id": 1, "category_name": "Standard", "created_dt": "2020-02-06T23:27:05.641334+00:00", "last_mod_dt": "2020-02-06T23:27:05.641334+00:00", "perks": [ "/v2/perks/1/", "/v2/perks/2/", "/v2/perks/3/" ], "resource_uri": "/v2/perk-categories/1/", "type": "EARN_PERK", },
Restrictions
Required scopes:
- PUBLIC
Required Filters
GET requests to the perk category endpoint that do not specify a PERK_CATEGORY_ID are required to append a business filter. Using an "IN" style query with the business filter is also not allowed with this resource.
Examples of VALID requests:
/v2/perk-categories/55/ /v2/perk-categories/?business=6&type=EARN_PERK
Examples of INVALID requests:
/v2/perk-categories/ /v2/perk-categories/?business__in=5,6
Querystring Parameters
Name | Type | Required | Description |
category_id | int | The perk category ID. | |
business | int | The ID of the business to which this perk category belongs. | |
type | string | The type of perks in this category. This can be either "EARN_PERK" or "REDEEM_PERK". Defaults to "EARN_PERK". |
Fields
Property Name | Type | Filterable | Description |
category_id | int | ✓ | The perk category ID. |
category_name | string | The name of the perk category. | |
business | Business | ✓ | The business to which this perk category belongs. |
type | string | ✓ | The type of perks in this category. This can be either "EARN_PERK" or "REDEEM_PERK". |
display_order | int | The order/priority in which this perk category should be displayed. The categories are listed in ascending order, if this is supplied. (e.g. a value of 1 is displayed first). null values are displayed last. | |
perks | Perk[] | The perks in this category, returned in display order. | |
created_dt | datetime | The date on which this perk category was created. | |
last_mod_dt | datetime | The date on which this perk category was last modified. |
POST
PATCH
DELETE
Promotion
A Promotion is a special perk created by a business. Currently, this includes just a Referral Promotion.
GET
GET /v2/promotions/{PROMOTION_ID}/
Example
Example Request
curl https://api.perkville.com/v2/promotions/8/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "business": "/v2/businesses/93/", "detail": "Enjoy a free cup of coffee on us!", "eligible_at_all_locations": true, "fine_print": "Only valid for first time customers.", "picture_uri": "https://www.perkville.com/images/deals/1234/123_500x500.jpg", "perk": "/v2/perks/1234", "title": "Free 12oz coffee", "type": "REFERRAL" }
Restrictions
Required scopes:
- PUBLIC
Querystring Parameters
Name | Type | Required | Description |
business | Business | The business ID the promotion belongs to. | |
location | Location | A location ID the promotion can belong to. If provided, and there is no location-specific promotion, the eligible_at_all_locations promotion will be returned. |
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The business ID the promotion belongs to. |
detail | string | The description of the promotion | |
eligible_at_all_locations | boolean | Indicates if this promotion is valid at all locations. | |
eligible_locations | Location[] | These are the locations at which this Promotion is eligible. Note that if eligible_at_all_locations is True, then eligible_locations won't be included. | |
fine_print | string | The detailed information and restriction of the promotion | |
perk | Perk | The Perk resource of this promotion | |
picture_uri | string | The uri of the picture associated with the promotion | |
picture_url | string | The url of the picture associated with the promotion | |
title | string | The name of the promotion | |
type | string | ✓ | The field that indicates the type of promotion. Options include 'REFERRAL' |
POST
PATCH
DELETE
Referral
Get or create a referral between two users at a specified business.
GET
GET /v2/referrals/{REFERRAL_ID}/
Example
Example Request
curl https://api.perkville.com/v2/referrals/5/ -H "Authorization: Bearer ryYMKAkopdwNb82FJTmxJ31L7T6K8z"
Example Response
{ "business": "/v2/businesses/5/", "completed_dt": "2016-03-31T20:46:14+00:00", "created_dt": "2016-03-31T20:16:40+00:00", "location": "/v2/locations/3/", "referral_content": "", "referral_date": "2016-03-31T20:16:40+00:00", "referral_from_user": "/v2/users/2/", "referral_source": "DIRECT_LINK", "referral_status": "COMPLETED", "referral_to_user": "/v2/users/5/", "referrer_conn_status": "ACTIVE", "resource_uri": "/v2/referrals/1/", "voucher_id": "/v2/vouchers/6/" }
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_REFERRAL
- USER_REFERRAL
If ADMIN_CUSTOMER_REFERRAL is present, referrals will be returned at businesses and locations that user is authorized to accesss.
If USER_REFERRAL is present, referrals will be returned at businesses and locations that involve that user as the referrer or referee.
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The uri of the Business of this referral. |
completed_dt | datetime | ✓ | The day and time the referral was marked as complete. This field is left blank if the referral status is not 'COMPLETED'. |
created_dt | datetime | ✓ | The day and time the referral was created in Perkville. |
location | Location | ✓ | The uri of the Location of this referral. |
referral_content | string | The message that was sent by the referrer to the referree. | |
referral_date | datetime | The day and time the referral was sent by the referrer to the referree. | |
referral_from_user | User | ✓ | The uri of the User who is the referrer. (SUPPORTS RELATIONAL QUERIES) |
referral_source | string | The part of Perkville's system where the referral came from. Options are 'WARM_REG' (Warm registration), 'LOGGED_IN' (Customer logged in), 'POS_SYNC' (Point-of-sale system sync), 'STAFF_SUBMIT' (Business staff submitted), 'API_SUBMITTED' (Submitted through API), 'FORWARDED' (Forwarded by original referred user'), 'TWITTER' (Distributed through Twitter), 'FACEBOOK' (Distributed through Facebook), 'DIRECT_LINK' (Linked directly using the "copy and paste" interface), 'MAILTO_EMAIL' (Mailed to using the mailto share button), 'PERKVILLE_EMAIL' (Sent through the "enter emails" interface), 'YEP2' ('Same as LOGGED_IN except they came through a point notification email') or blank if the referral source is unknown. | |
referral_status | string | ✓ | Current status of the referral. Options are 'SENT' (the referral has been sent by the referrer, but not completed by the referree), 'COMPLETED' (the referree has earned points at the business and successfully completed the referral), and 'VOID' (the referral has been voided). |
referrer_conn_status | string | The business connection status of the referrer at the time the referral was sent. Options are 'ACTIVE', 'INACTIVE', 'PENDING', 'IMPORTED', 'NOCONN', or blank if the business connection status is unknown. | |
referral_to_user | User | ✓ | The uri of the User who is the referree. (SUPPORTS RELATIONAL QUERIES) |
resource_uri | string | The uri of this Referral record in Perkville's API. | |
voucher | Voucher | The uri of the Voucher that was created from this referral. Please note this field will be null unless the referral offer has already been claimed by the referree. |
POST
POST /v2/referrals/
Example
Example Request
curl https://api.perkville.com/v2/referrals/ -H "Authorization: Bearer ryYMKAkopdwNb82FJTmxJ31L7T6K8z" -d '{"business": "/v2/businesses/1/", "location": "/v2/locations/2/", "referral_from_user": "/v2/users/261998/", "referral_to_email": "edward_test@perkville.com"}'
Example Response
{ "business": "/v2/businesses/1/", "completed_dt": null, "created_dt": "2015-05-12-T18:39:07+00:00", "distribution_type": "EMAIL", "location": "/v2/locations/2/", "referral_content": "", "referral_from_user": "/v2/users/261998/", "referral_source": "API_SUBMITTED", "referral_status": "SENT", "referral_to_email": "edward_test@perkville.com", "referree_external_id": "", "referree_external_id_type: "", "referrer_conn_status": "ACTIVE", "resource_uri": "/v2/referrals/1/", "voucher": null }
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_INFO
- USER_CUSTOMER_INFO
- At least one of these:
- ADMIN_CUSTOMER_REFERRAL
- USER_REFERRAL
If ADMIN_CUSTOMER_REFERRAL is present, you may create referrals on behalf of customers who belong to the Business for which this user is a staff member. If both the referral_from_user and the referral_to_email are already connected to the specified business and submit_as_referrer is set to false (default), the referral will be created with a referral_status of COMPLETED. If the referral_to_email is not connected to the specified business the referral will be created with a status of SENT.
If USER_REFERRAL is present, you may create referrals only for the user associated with the bearer token. This will create a referral from the user to the email address specified, and will have a referral_status of SENT. If the referral_to_email is already a customer of the specified business the referral will be rejected.
Parameters
Property Name | Type | Description |
business | Business | The uri of the Business of this referral. |
location | Location | The uri of the Location of this referral. This is an OPTIONAL parameter. |
referral_from_user | User | The uri of the User who is sending the referral. If USER_REFERRAL scope is present, this field will always be equal to the user making the referral request. |
referral_to_email | string | The email address of the person being referred to the specified business. |
referral_to_first_name | string | The first name of the person being referred. This is an optional parameter. |
referral_to_last_name | string | The last name of the person being referred. This is an optional parameter. |
referral_content | string | A personalized note to be sent along with the referral. This is an OPTIONAL parameter. |
send_referral_email | boolean | Determines whether to send a referral email to the user being referred. An input of true will send an email and an input of false will not send an email. This is an OPTIONAL parameter and if excluded will automatically default to true. |
submit_as_referrer | boolean | Only applicable to ADMIN_CUSTOMER_REFERRAL scopes. When set to true, if the referral_to_email has an existing connection with the business, the referral will be rejected. When set to false, the referral will be created regardless of the referral_to_email's connection with the business. This is an OPTIONAL parameter, and if excluded will automatically default to false. |
Returns
A 201 response with a JSON object of the created Referral if successful.
PATCH
DELETE
Scope
Scopes are different levels of authorization that control what a bearer token can and can't access. Calling this endpoint will return a list of all scopes for the bearer token making the request.
GET
GET /v2/scopes/
Example
Example Request
curl https://api.perkville.com/v2/scopes/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "scope": "PUBLIC" }, { "scope": "USER_CUSTOMER_INFO" }, { "scope": "USER_REDEEM" }, { "scope": "ADMIN_CUSTOMER_INFO" }, { "scope": "ADMIN_CUSTOMER_REDEEM" }, { "scope": "ADMIN_CUSTOMER_GRANT_POINTS" }, { "scope": "ADMIN_PERK" }
Restrictions
None
Fields
Property Name | Type | Filterable | Description |
scope | string | The name of the scope. |
POST
PATCH
DELETE
Transaction
A Transaction is a single event where a user earns or spends points. An example of a Transaction would be "Bob checked in at Yoga Studio Extreme on March 5th 2015 and earned 15 points."
In addition, you can retrieve a specific transaction or a list of transactions.
NOTE: If you are requesting a list of transactions using the ADMIN_CUSTOMER_INFO scope, we require you to append a user filter, e.g. ?user={{USER_ID}}
or a filter related to the user model, e.g. ?user__emails__email={{USER_EMAIL}}
. For more information on related fields, please see the documentation for the user resource. If you are using the USER_CUSTOMER_INFO scope a user filter is not required since those requests will already be filtered by records belonging to the user making the request.
GET
GET /v2/transactions/{TRANSACTION_ID}/
Example
Example Request
curl https://api.perkville.com/v2/transactions/232442/ -H "Authorization: Bearer accesstoken123abc"" -H "Content-Type: application/json"
Example Response
{ 'business': '/v2/businesses/25/', 'location': '/v2/locations/2/', 'perk': '/v2/perks/397/', 'title': 'Free Hoodie', 'points': 300, 'quantity': 1, 'resource_uri': '/v2/transactions/232442/', 'trans_source_id': '', 'transaction_dt': '2015-01-30T23:54:04.147208+00:00', 'transaction_id': 3144, 'user': '/v2/users/263727/', 'voucher': '/v2/vouchers/552044/' }
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_INFO
- USER_CUSTOMER_INFO
If ADMIN_CUSTOMER_INFO is present, you can retrieve transaction records from businesses and locations that the user making the request is an administrator of.
If USER_CUSTOMER_INFO is present, you can retrieve transaction records for the user making the request.
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The uri of the Business of this transaction |
location | Location | ✓ | The uri of the Location of this transaction. |
perk | Perk | ✓ | The uri of the Perk of this transaction. (SUPPORTS RELATIONAL QUERIES) |
title | string | The user-readable description of what this transaction was actually for. e.g., "Checkin" or "Free Hoodie" | |
classification | string | The classification of the perk tied to this transaction. Either "EARN" or "REDEEM", indicating if this rule is for receiving points or for spending. | |
points | int | The points that were either spent (REDEEM type perk) or earned (EARN type perk) with this transaction. | |
quantity | int | The quantity of the transaction -- usually this is used with the EARN transaction event for a dollar spent rule. | |
trans_source_id | string | This field may be present if the transaction was created via an API. It is used to ensure that the transaction is unique at this business. Limit 128 characters. | |
transaction_dt | datetime | ✓ | The date and time the transaction was created. |
transaction_id | int | The ID number for the transaction. | |
transaction_status | string | ✓ | The current status of the Transaction. The options are ACTIVE, VOID, VOID_REF. When a transaction is voided two the things happen. The transaction gets updated with a status of VOID, and a new transaction, for the negative amount of the original transaction, is created with the status VOID_REF. The transaction_reference field described below will also be used in order for the original transaction to reference the transaction that voided it and vice versa. |
transaction_reference | Transaction | Certain types of transactions may be created in reference to another transaction. In those cases this field is used. | |
user | User | ✓ | The uri of the User associated with the transaction. (SUPPORTS RELATIONAL QUERIES) |
voucher | Voucher | The uri of the Voucher used in the transaction. |
POST
POST /v2/transactions/
Example
Example Request
curl https://api.perkville.com/v2/transactions/ -H "Authorization: Bearer ryYMKAkopdwNb82FJTmxJ31L7T6K8z" -H "Content-Type: application/json" -d '{ "business": "/v2/businesses/1/", "location": "/v2/locations/2/", "perk": "/v2/perks/397/", "quantity": "1", "user_email": "edward_test@perkville.com", "first_name": "Edward", "last_name": "McFudge" }'
Example Response
{ 'business': '/v2/businesses/25/', 'location': '/v2/locations/2/', 'perk': '/v2/perks/397/', 'points': 300, 'quantity': 1, 'resource_uri': '/v2/transactions/232442/', 'trans_source_id': '', 'transaction_dt': '2015-01-30T23:54:04.147208+00:00', 'transaction_id': 3144, 'user': '/v2/users/263727/', 'voucher': '/v2/vouchers/552044/' }
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_GRANT_POINTS
- ADMIN_CUSTOMER_REDEEM
- USER_REDEEM
- At least one of these:
- ADMIN_CUSTOMER_INFO
- USER_CUSTOMER_INFO
When creating a Transaction, the following fields must always be present:
- Business URI
- Location URI or External location ID
- Perk URI
- Quantity
- Trans source ID (Not technically required, but strongly recommended)
For identifying whom should receive this Transaction, there are a few options:
- User URI
- User email
- External member ID and External system ID
Alternatively, if the external member ID and external system IDs are present, we'll look up the User, and add that Transaction for that User. If no User has the provided external member info, we'll create a User from the provided email, award the Transaction, and then send the user an invitational email. If no email was provided in the latter case, the Transaction will fail.
If ADMIN_CUSTOMER_GRANT_POINTS is present, you may create EARN transactions for any customers who belong to the Business for which this user is a staff member.
If USER_REDEEM is present, you may create a REDEEM transaction for only the user associated with the bearer token. This will create a Voucher using the initial voucher status for the given perk. The voucher_start_as_used parameter can be used as an override to force the voucher to be created with a USED status.
If ADMIN_CUSTOMER_REDEEM is present, you may create REDEEM transactions for any customers who belong to the Business for which this user is a staff member. This will create a Voucher using the initial voucher status for the given perk, unless voucher_start_as_unused is set to True.
Generally, if you'd like all vouchers for a specific perk to be created with a specific status, rather than using on of the above mention voucher_start_as_* parameters, you should use the initial_voucher_status parameter on the Perk resource. This feature is also available via the web interface.
Parameters
Property Name | Type | Description |
business | Business | The uri of the Business of this transaction |
location | Location | The uri of the Location of this transaction. Include this OR the "external_location_id" parameter, but not both. PLEASE NOTE When creating redeem transactions for perks using the must_redeem_at_home_location option, the user's home location MUST be used. A user's home location can be found using the Connection resource. |
external_location_id | string | The external_location_id of the Location you'd like to use for this transaction. Include this OR the "location" parameter, but not both. |
perk | Perk | The uri of the Perk of this transaction |
quantity | int | The quantity of the transaction -- usually this is used with the EARN transaction event for a dollar spent rule. If you'd like to deduct points for something like a dollar spent rule (e.g. in the event of a refund), you may post a negative quantity. Not typically used with a REDEEM type perk. |
trans_source_id | string | This is an OPTIONAL parameter. This field is guaranteed to be unique for a business. API clients may use this field to ensure that the posted transaction is unique. For example, imagine an API client is awarding points for a customer's purchase. It may be a good idea to pass in the ID of the purchase into this field, avoiding the case where a customer may be awarded points twice for a purchase. |
transaction_dt | datetime | This is an OPTIONAL parameter. It defaults to the current datetime. If passed in, we'll set the transaction_dt of the transaction to this value. This can be useful if posting transactions that occurred sometime in the past. This value may not be in the future, or more than 1 year in the past. This value must be in UTC! The following formats are valid -- '%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d' |
user_email | string | This is an OPTIONAL parameter. Include this or "user" but not both. If this user_email record exists in our database, we'll apply the transaction to that user. Otherwise, we'll create a new user with the passed user_email, first_name, and last_name. |
user | user | The uri of the User of this transaction. This is an OPTIONAL parameter. Include this or "user_email" but not both. |
first_name | string | Only include if you're using user_email instead of user. If this user_email record exists in our database, we'll apply the transaction to that user. Otherwise, we'll create a new user with the passed user_email, first_name, and last_name. |
last_name | string | Only include if you're using user_email instead of user. If this user_email record exists in our database, we'll apply the transaction to that user. Otherwise, we'll create a new user with the passed user_email, first_name, and last_name. |
birthday | date | This is an OPTIONAL parameter. The user's birthday as "YYYY-MM-DD". If the user already exists, and does not have a birthday on file, we will update the user with the provided birthday. |
external_member_id | string | This is an OPTIONAL parameter. This can serve as a separate identifier for a User. If included, this external_member_id will be used to identify the User. If the external_member_id does not already exist, then it will become associated with user/user_email passed into the request. |
external_system_id | string | This is an OPTIONAL parameter, however must be included when using the external_member_id parameter. This is used to identify the external membership system. So if the membership system is something like "Example Software", you could use "EXAMPLE_SOFTWARE" as the ID |
send_email | boolean | Indicates if we should send an email to the user for this transaction. Defaults to true if nothing is passed in. Perks that the business has configured to not trigger an email will never do so, regardless of the value of this parameter. |
can_receive_emails | boolean | Indicates if we should send any emails to this user. Defaults to true if nothing is passed in. Please note that this parameter only applies to newly created users. If the user/email already exists, this parameter will be ignored. |
voucher_start_as_used | boolean | Only applicable to USER_REDEEM scopes. If this is true AND the perk is redeem-type perk, the user's voucher will be created in a USED status. This defaults to false, as normally users will need to redeem the voucher themselves. |
voucher_start_as_unused | boolean | Only applicable to ADMIN_CUSTOMER_REDEEM scopes. If this is true AND the perk is redeem-type perk, the user's voucher will be created in a UNUSED status. This defaults to false, as normally perks redeemed by admins on a user's behalf are marked as USED. |
limit_to_once_per_calendar_day | boolean | This is an OPTIONAL parameter. Defaults to false. If this is true, each user may only earn this perk once per day, based on the timezone of the location. |
Returns
A 201 response with a JSON object of the created Transaction if successful. Note that the "voucher" property will only appear if the transaction actually has a voucher.
PATCH
DELETE
User
A User is a single person using the Perkville platform. Usually, Users have one or more Connections, which represent their customer relationship to a Business. This object includes contact information, such as email address.
Note: Instead of a user ID in the uri, you can call GET /v2/users/me/
. This will return the User which belongs to the Bearer Token.
GET
GET /v2/users/{USER_ID}/
Example
Example Request
curl https://api.perkville.com/v2/users/me -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "birthday": "1909-04-23", "connections": [ "/v2/connections/3/" ], "emails": [ { "email": "john.doe@example.org", "primary": true } ], "first_name": "John", "last_mod_dt": "2016-06-02T14:30:45+00:00", "last_name": "Doe", "phone_number": "555-867-5309", "resource_uri": "/v2/users/261998/", "user_id": 261998 }
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_INFO
- USER_CUSTOMER_INFO
If USER_CUSTOMER_INFO is present, the only accessible record is the User associated with the access token.
If ADMIN_CUSTOMER_INFO is present, the only accessible records are those Users who are customers of the Business which the user associated with the access token is a staff member. For example, if the User associated with the access token is a staff member at Business 1, this will return all users who are customers of Business 1.
If ADMIN_IDENTIFY_USER scope is available, the bearer token user is allowed to implement the Identify User Flow. The resulting identification code can then be used as a filter for this resource. A successful response will include a list, with a single user object, found by using the code.
Fields
Property Name | Type | Filterable | Description |
user_id | int | ✓ | The ID of this User |
first_name | string | The user's first name | |
last_mod_dt | datetime | ✓ | The date and time that this record was last modified in UTC |
last_name | string | The user's last name | |
phone_number | string | The user's phone number | |
birthday | date | The user's birthday as "YYYY-MM-DD" | |
emails | Object[] | ✓ | These are all the emails which are registered to this user account. (SUPPORTS RELATIONAL QUERIES) Note that emails in Perkville are unique. No two users share the same email address. Objects in this array have two keys, "email" and "primary". To filter users by email, use the quesystring parameter "emails__email". E.g., "https://api.perkville.com/v2/users/?emails__email=foo@foo.com". |
connections | Connection[] | These objects represent a user's relationship to a business. | |
code | string | ✓ | Used only as a filter for applications implementing the Identify User Flow. Response objects do not have a "code" property. |
POST
PATCH
DELETE
User Business Agreement
A User Business Agreement is a record of a User's agreement to a specific version of a Business' Agreement.
These records are point-in-time snapshots of the User's agreement to the Business' Agreement. These records are primarily intended for initial agreement capture. These records are not intended as a source of truth for the User's ongoing agreement status. For instance, if a person has opted out of communication from outside of Perkville, this will not be reflected in the User Business Agreement record.
GET
GET /v2/user-business-agreements/{USER_BUSINESS_AGREEMENT_ID}/
Example
Example Request
curl https://api.perkville.com/v2/user-business-agreements/1/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "agreement_dt": "2020-02-06T23:27:05.641334+00:00", "agreement_id": 1, "agreement_version": "/v2/agreement-versions/1/", "business": "/v2/businesses/2/", "email": "example@example.com", "first_name": "John", "last_name": "Doe", "resource_uri": "/v2/user-business-agreements/1/", "user": "/v2/users/1/" },
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_INFO
- USER_CUSTOMER_INFO
If USER_CUSTOMER_INFO is present, the only accessible records are those User Agreements which belong to the User associated with the access token.
If ADMIN_CUSTOMER_INFO is present, the only accessible records are those User Agreements which belong to the Business which the User associated with the access token is an ADMIN staff member. For example, if the User associated with the access token is an ADMIN staff member at Business 1, this will return all User Agreements who belong to Business 1.
Required Filters
GET requests to the user agreement endpoint that do not specify a USER_AGREEMENT_ID are required to append a business filter. Using an "IN" style query with the business filter is also not allowed with this resource.
Examples of VALID requests:
/v2/user-business-agreements/55/ /v2/user-business-agreements/?business=6 /v2/user-business-agreements/?business=6&user__in=1123,1125 /v2/user-business-agreements/?business=6&user=1125&agreement_id=1
Examples of INVALID requests:
/v2/user-business-agreements/ /v2/user-business-agreements/?business__in=5,6 /v2/user-business-agreements/?user=1122 /v2/user-business-agreements/?agreement_id=1
Fields
Property Name | Type | Filterable | Description |
id | int | ✓ | The user agreement ID. |
agreement_id | id | ✓ | The agreement to which this version belongs. |
agreement_version | AgreementVersion | The uri of the agreement version to which this user agreement belongs. | |
user | User | ✓ | The uri of the user to which this user agreement belongs. |
business | Business | ✓ | The uri of the business to which this user agreement belongs. |
string | The email address of the user. | ||
first_name | string | The first name of the user. | |
last_name | string | The last name of the user. | |
agreement_dt | datetime | The date on which this user confirmed their choice. |
POST
PATCH
DELETE
Voucher
A Voucher represents a redeemed reward. It's like a coupon -- The user exchanges a voucher for a physical reward.
A Voucher is created when a customer redeems a reward.
Vouchers can be "Marked as Used", indicating that the Voucher has been used and can't be redeemed again.
Vouchers can be created via the API, but not through this resource! Instead, use the Transaction resource, and post a REDEEM type Transaction.
If a business have disallowed canceled members from earning or redeeming points, vouchers for canceled members will not show up in the API.
GET
GET /v2/vouchers/{VOUCHER_ID}/
Example
Example Request
curl https://api.perkville.com/v2/vouchers/39437/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "business": "/v2/businesses/1/", "marketplace_business": null, "created_datetime": "2014-10-28T16:04:06+00:00", "expiration_date": "2014-12-26", "external_coupon_code": null, "location": "/v2/locations/10/", "network_reward_url": null, "perk": "/v2/perks/96/", "transaction": "/v2/transactions/5503404/", "point_cost": 24, "resource_uri": "/v2/vouchers/39437/", "status": "UNUSED", "user": "/v2/users/262251/", "voucher_id": 39437 }
Restrictions
Required scopes:
- PUBLIC
- At least one of these:
- ADMIN_CUSTOMER_REDEEM
- USER_CUSTOMER_INFO
If USER_CUSTOMER_INFO is present, the only accessible records are those which belong to the User associated with the access token.
If ADMIN_CUSTOMER_REDEEM is present, the only accessible records are those which belong to the Business which the User associated with the access token is a staff member. For example, if the User associated with the access token is a staff member at Business 1, accessible vouchers include those associated at Business 1.
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The Business where the voucher was created. In most cases, this will also indicate where the voucher can be redeemed. |
marketplace_business | Business | (Depricated) If the voucher is for a marketplace reward, this property will indicate the business where the voucher can be redeemed. | |
created_datetime | datetime | The datetime of when the voucher was created in UTC | |
expiration_date | datetime | The datetime when the voucher expires, in UTC | |
location | Location | ✓ | The voucher can be redeemed at this Location |
network_reward_url | string | A Reward URL displayed on a voucher instance | |
perk | Perk | ✓ | The voucher was created by spending the point at this Perk |
transaction | Transaction | The transaction associated with creating this voucher. In order to display the details of the perk AT THE TIME it was redeemed, you need to look at the transaction record. Any of a perks details may have been edited since the voucher was created. | |
point_cost | int | The voucher cost this many points to redeem | |
status | string | Indicates whether this voucher has been used or not. Values include 'USED', 'UNUSED', 'EXPIRED', 'EMAILED_REWARD', 'PROCESSING', 'CREDITED', 'ISSUED', 'VOIDED' | |
voucher_id | string | ✓ | The voucher ID of this voucher. Often referred to as the "Voucher Code" on the Perkville website. |
user | User | ✓ | The user who owns the voucher. (SUPPORTS RELATIONAL QUERIES) |
external_coupon_code | string | The business' internal identifier for this perk. Businesses typically use it instead of the voucher code when representing perkville vouchers in third party systems. If the external_coupon_code is present, display it instead of the voucher code. |
POST
PATCH
PATCH /v2/vouchers/{VOUCHER_ID}/
Example
Example Request
curl --request PATCH https://api.perkville.com/v2/vouchers/39437/ -H "Authorization: Bearer ryYMKAkopdwNb82FJTmxJ31L7T6K8z" -H "Content-Type: application/json" -d '{ "status": "USED" }'
Example Response
202 Accepted { "business": "/v2/businesses/1/", "created_datetime": "2014-10-28T16:04:06+00:00", "expiration_date": "2014-12-26", "external_coupon_code": null, "location": "/v2/locations/10/", "perk": "/v2/perks/96/", "transaction": "/v2/transactions/5503404/", "point_cost": 24, "quantity": 1, "resource_uri": "/v2/vouchers/39437/", "status": "USED", "user": "/v2/users/262251/", "voucher_id": 39437 }
Restrictions
Required scopes:
- PUBLIC
- ADMIN_CUSTOMER_REDEEM
Accessible records are those which belong to the Business which the User associated with the access token is a staff member. For example, if the User associated with the access token is a staff member at Business 1, accessible vouchers include those associated at Business 1.
Parameters
Property Name | Type | Description |
status | string | The status of the voucher. Valid values are 'USED', 'UNUSED', 'EXPIRED'. |
expiration_date | date | The date when this voucher will expire using %Y-%m-%d' format. |
location | Location | The uri of the Location for this voucher. Include this OR the "external_location_id" parameter, but not both. |
external_location_id | string | The external_location_id of the Location for this voucher. Include this OR the "location" parameter, but not both. |
Returns
202 Accepted with a JSON object of the patched Voucher.
DELETE
Rewards Program Rules
The following endpoints give a more complete view of the rewards program. These endpoints are meant to aid your API client by providing you an ordered list of rules, their associated bonuses, and any user-specific details pertaining to those rules and bonuses (like progress or eligibility).
Results are intended to mimic how our web interface displays the rewards program to either logged-in users (USER_CUSTOMER_INFO scopes) or logged-out users (PUBLIC scopes).
Much of the information in these endpoints is available in the Perk resource. However, these Rewards Program Rules endpoints include additional key information, such as current active bonuses for an Earning rule and the user's progress toward those bonuses (if applicable).
Earning Rules
The Earning resource returns a business' rewards program earning rules from the perspective of a user.
This resource is location-specific, as some locations have different earning rules available. For instance, a location may have different date-range bonuses than another location. If you do not provide a `loc_id` filter, we will return the earning perks for the user's primary location or the business' primary location.
Earning perks are returned in the order in which we would display them to users. If you are using this resource to display perks in your application, it is recommended that you respect the order in which these perks are returned.
GET
GET /v2/earning/
Example
Example Request
curl https://api.perkville.com/v2/earning/?business=2&loc_id=1&view_as_user=true -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "meta": { "limit": 20, "offset": 0 }, "objects": [ { "business": "/v2/businesses/2/", "completes_referral": true, "date_range_bonuses": [ { "from_date": "2023-03-21", "multiplier": "5.00", "perk_id": 303, "to_date": "2023-05-31" } ], "description": "", "display_name": "Check-in", "display_order": null, "frequency_bonuses": [ { "bonus_points": 200, "earned_count": 0, "frequency": "FROM_DATE", "frequency_bonus_perk_id": 405, "perk_id": 302, "required_to_earn": 5, "start_date": "2021-01-01" } ], "loc_id": 1, "perk_id": 246, "points": 2, "time_bonuses": [ { "multiplier": "2.00", "perk_id": 301, "time_periods": { "Thursday": [ "3 pm to 4 pm", "5 pm to 6 pm" ], } } ], "title": "Check-in", "type": "STANDARD" }, ] }
Restrictions
Required scopes:
- At least one of these:
- PUBLIC
- USER_CUSTOMER_INFO
If USER_CUSTOMER_INFO is present, you can optionally see the redeeming rules from the perspective of the authenticated user.
If PUBLIC is present, you can see the earning rules from the perspective of a logged-out user.
The view_as_user parameter must be set to `true` if you want to see the earning rules from the perspective of the bearer token user.
Querystring Parameters
Name | Type | Required | Description |
business | Business | ✓ | The business ID. |
loc_id | Location | The location ID. While not a required filter, this resource will be filtered by a location. If USER_CUSTOMER_INFO scopes are available, this endpoint returns perks for the user's primary location. Otherwise, it returns perks for the business' primary location. | |
view_as_user | Boolean | Only applicable to USER_CUSTOMER_INFO scopes. Indicates if you would like to view the rewards program as the bearer token user. If this is false, you will see the rewards program as a logged-out user. Defaults to false. |
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The business ID. This filter is required. |
perk_id | int | The perk ID | |
description | string | The long form user-facing description of this rule. Usually this is used to give detailed information about the Perk. | |
loc_id | int | The location ID. This is the location at which you are viewing the rewards program. | |
points | int | The number of points that this rule is worth | |
display_name | string | This is the name that is displayed to the user. It is usually the same as the title, but can be different for certain perks, like REFERRAL or REGISTRATION type perks. | |
title | string | The short title of this Perk | |
type | string | This is a special field which indicates how the Perk is used. Options include 'STANDARD', 'BIRTHDAY', 'CHECKIN', 'REFERRAL', 'REGISTRATION', 'TWITTER_POST', 'VISITOR'. | |
completes_referral | boolean | When this field is true, when a customer earns this perk, if that customer has an open referral where he or she is the one who was referred, that referral should be completed. | |
category | dict | The category of the perk. This is a dictionary with the following keys: 'category_id', 'category_name', 'display_order'. For display purposes, perks should be grouped by category. Perks with categories are displayed first, followed by perks without categories. | |
display_order | int | The order/priority in which this perk should be displayed. The perks are listed in ascending order, if this is supplied. (e.g. a value of 1 is displayed first) | |
date_range_bonuses | dict[] | List of date range bonuses, in the format of {'multiplier': 'float', 'from_date': 'date', 'to_date': 'date', 'perk_id': int}. The perk_id is a foreign key to the PerkResource. | |
frequency_bonuses | dict[] | List of frequency bonuses, in the format of {'required_to_earn': int, 'frequency': 'string', 'bonus_points': int, 'earned_count': int, 'frequency_bonus_perk_id': int, 'start_date': date, 'perk_id': int} The "frequency" value can be WEEKLY, MONTHLY, or FROM_DATE. "earned_count" will only be a non-zero value if the USER_CUSTOMER_INFO scope is present, and the user associated with the bearer token has progress toward the bonus. The 'start_date' is when this frequency bonus began. The frequency_bonus_perk_id is a foreign key to the FrequencyBonusPerkResource. The perk_id is a foreign key to the PerkResource. | |
time_bonuses | dict[] | List of time bonuses, in the format of {'multiplier': float, 'time_periods': {'weekday string': ['time range string',]}, 'perk_id': int} This is best illustrated in the "Example Response" above. The perk_id is a foreign key to the PerkResource. |
Redeeming Rules
The Redeeming resource returns a business' redeemable rewards from the perspective of a user.
This resource defaults to location-specific, as some locations have different rewards available. If you do not provide a `loc_id` filter, we will return the perks for the user's primary location or the business' primary location.
To override the location-specific filter, you can set the `all_locs` parameter to `true`. This will return all perks available at all locations for the business.
Redeem perks are returned in the order in which we would display them to users. If you are using this resource to display perks in your application, it is recommended that you respect the order in which these perks are returned.
Note: Not all redeem perks are visible or available to all users. Therefore, there may be some perks retrievable from the Perk endpoint, but not accessible from this endpoint for the given user.
GET
GET /v2/redeeming/
Example
Example Request
curl https://api.perkville.com/v2/redeeming/?business=2&loc_id=1&view_as_user=true -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "business": "/v2/businesses/2/", "description": "", "display_order": 3, "external_reward_url": null, "fine_print": "", "from_date": null, "loc_id": 1, "must_redeem_at_home_location": false, "perk_id": 26, "picture_card": null, "points": 300, "redemption_instructions": "Print or show on phone", "redemption_limit_count": 5, "redemption_limit_interval": "DAY", "redemption_limit_interval_count": 1, "required_level": null, "title": "Shades", "to_date": null, "type": "STANDARD", "user_redemption_limit_info": { "has_met_limit": false, "next_redemption_opportunity": "2023-04-01", "redemptions_remaining": 5 }, "valid_customer_attributes": [] },
Restrictions
Required scopes:
- At least one of these:
- PUBLIC
- USER_CUSTOMER_INFO
If USER_CUSTOMER_INFO is present, you can optionally see the redeeming rules from the perspective of the authenticated user.
If PUBLIC is present, you can see the redeeming rules from the perspective of a logged-out user.
The view_as_user parameter must be set to `true` if you want to see the redeeming rules from the perspective of the bearer token user.
Querystring Parameters
Name | Type | Required | Description |
business | Business | ✓ | The business ID. |
loc_id | Location | The location ID. While not a required filter, this resource will be filtered by a location. If USER_CUSTOMER_INFO scopes are available, this endpoint returns perks for the user's primary location. Otherwise, it returns perks for the business' primary location. | |
all_locs | Boolean | If set to `true`, this will return all perks available at all locations for the business. If this parameter is `true`, the `loc_id` parameter is ignored. | |
view_as_user | Boolean | Only applicable to USER_CUSTOMER_INFO scopes. Indicates if you would like to view the rewards program as the bearer token user. If this is false, you will see the rewards program as a logged-out user. Defaults to false. |
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The business ID |
perk_id | int | The perk ID | |
description | string | The long form user-facing description of this rule. Usually this is used to give detailed information about the Perk. | |
points | int | The number of points that this rule is worth | |
title | string | The short title of this Perk | |
type | string | This is a special field which indicates how the Perk is used. Options include 'STANDARD' and 'EXTERNAL_REWARD'. | |
must_redeem_at_home_location | boolean | For businesses that sync membership information, this is an option that can be configured when creating a perk that requires users to redeem at their home location. | |
redemption_limit_interval | string | One of the following - 'NO_REDEMPTION_LIMIT', 'DAY', 'MONTH', 'YEAR', 'ALL_TIME'. Together with redemption_limit_interval_count and redemption_limit_count, this indicates how many times this perk can be redeemed within the interval. | |
redemption_limit_count | int | Populated if redemption_limit_interval is anything other than 'NO_REDEMPTION_LIMIT', and indicates how many times the perk can be redeemed in the given span of time. If the rule is that this can be redeemed "2 times in 10 Days", 2 is the redemption_limit_count. | |
redemption_limit_interval_count | int | Populated if redemption_limit_interval is 'DAY', 'MONTH' or 'YEAR', and indicates the span of time with which the redemption limit applies. If the rule is that this can be redeemed "2 times in 10 Days", 10 is the redemption_limit_interval_count. | |
user_redemption_limit_info | dict | Populated if there is a redemption limit, in the format of {'has_met_limit': boolean, 'redemptions_remaining': int, 'next_redemption_opportunity': date}. has_met_limit is a boolean indicating whether the user has met their redemption limit for this perk. redemptions_remaining is the number of times the user can still redeem this perk. next_redemption_opportunity is the date on which the user can redeem this perk again. | |
required_level | Level | Indicates the minimum level, based on point_floor, that a user must unlock before they can redeem this perk. Use the Connection endpoint to determine a user's level at a business. | |
start_date | date | Populated if the perk's available start date has been set. | |
end_date | date | Populated if the perk's available end date has been set. | |
picture_card | string | If this perk has a photo, the URL of the photo is available in this attribute. | |
fine_print | string | Any specific rules that applies to the perk | |
external_reward_url | string | A URL to a third party reward provider | |
redemption_instructions | string | This text will be displayed on the voucher the customer receives when they redeem this perk. | |
valid_customer_attributes | Custom Attribute Value[] | Used when the business has chosen to restrict the customers who can transact with this perk by those who have been assigned at least one of the listed values. This returns a list of Custom Attribute Value objects, including the name of the Custom Attribute Value and Custom Attribute {'custom_attribute': 'uri', 'custom_attribute_display_name': 'Custom Attribute Name', 'custom_attribute_value': 'uri', 'custom_attribute_value_display_name': 'Custom Attribute Value Name', 'order': null} | |
display_order | int | The order/priority in which this perk should be displayed. The perks are listed in ascending order, if this is supplied. (e.g. a value of 1 is displayed first) | |
loc_id | int | The location ID. This is the location at which you are viewing the rewards program. Will be null if viewing all locations. |
User Voucher
This endpoint returns the viewable vouchers from the perspective of a user.
In addition to much of the information returned by the Voucher endpoint, this endpoint also returns details like the title, description, fine print, and image associated with the voucher. All of which makes it easier to display what a voucher should look like to the user.
This endpoint also allows USER_CUSTOMER_INFO scopes to PATCH voucher status to USED. This differs from the Voucher endpoint, which only allows ADMIN_CUSTOMER_REDEEM scopes to patch voucher status.
Vouchers are returned in the order in which we would display them to users. If you are using this resource to display vouchers in your application, it is recommended that you respect the order in which these vouchers are returned.
This endpoint supports filtering by business or directly accessing a specific voucher by its voucher_id.
GET
GET /v2/user-vouchers/{VOUCHER_ID}/
Example
Example Request
curl https://api.perkville.com/v2/user-vouchers/39437/ -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "business": "/v2/businesses/1/", "created_datetime": "2014-10-28T16:04:06+00:00", "details": "These are the details of the voucher", "expiration_date": "2014-12-26", "external_coupon_code": null, "location": "/v2/locations/10/", "network_reward_url": null, "perk": "/v2/perks/96/", "perk_description": "This is the description of the perk", "perk_fine_print": "This is the fine print of the perk", "point_cost": 24, "promotion_fine_print": "This is the fine print of the promotion", "status": "UNUSED", "title": "Free class", "user": "/v2/users/262251/", "voucher_id": 39437 }
Restrictions
Required scopes:
- USER_CUSTOMER_INFO
The only accessible records are those which belong to the User associated with the access token.
Querystring Parameters
Name | Type | Required | Description |
business | Business | The business ID. Required if not filtering by voucher_id. |
Fields
Property Name | Type | Filterable | Description |
business | Business | ✓ | The Business where the voucher was created. In most cases, this will also indicate where the voucher can be redeemed. |
created_datetime | datetime | The datetime of when the voucher was created in UTC | |
details | string | The details of the voucher. | |
expiration_date | date | The date when the voucher expires, in UTC | |
location | Location | The voucher can be redeemed at this Location | |
network_reward_url | string | A Reward URL displayed on a voucher instance | |
perk | Perk | The voucher was created by spending the point at this Perk | |
title | string | The title of the voucher. This may differ from the title of the perk, if the perk title changed after the voucher was created. | |
perk_description | string | The description of the associated perk. | |
perk_fine_print | string | The fine print of the associated perk. | |
promotion_fine_print | string | The fine print of the associated promotion. | |
point_cost | int | The voucher cost this many points to redeem | |
status | string | Indicates whether this voucher has been used or not. Values include 'USED', 'UNUSED', 'EXPIRED', 'EMAILED_REWARD', 'PROCESSING', 'CREDITED', 'ISSUED', 'VOIDED' | |
voucher_id | string | ✓ | The voucher ID of this voucher. Often referred to as the "Voucher Code" on the Perkville website. |
user | User | The user who owns the voucher. | |
external_coupon_code | string | The business' internal identifier for this perk. Businesses typically use it instead of the voucher code when representing perkville vouchers in third party systems. If the external_coupon_code is present, display it instead of the voucher code. |
Getting Started with API Reports
The following reporting endpoints allow a staff member to run reports on business data using our API. While these endpoints are a part of APIv2, some of their basic functionality differs from the resources endpoints.
Querystring Parameters
Unlike resource endpoints, the querystring parameters of a GET
request are not used to filter
a resulting list of objects. They are instead used to set the parameters of a report we will be running on
a staff member's behalf.
The Querystring Parameters table of each endpoint documents the parameters that can be set for a report.
Business Primary Key
A business
querystring parameter is always required.
GET https://api.perkville.com/v2/top-earners/?business=1234
Greater Than/Less Than Filter
Greater Than/Less Than Filters are not supported in the reporting API. If a report accepts
from_date
and to_date
parameters, you should set those values when needed.
GET https://api.perkville.com/v2/top-earners/?business=1234&from_date=2017-08-01&to_date=2017-08-31
"In" filter
The "In" filter can be used to specify multiple values for parameters whose type has []
appended.
GET https://api.perkville.com/v2/top-earners/?business=1234&locations__in=5,6
Top Earners
This endpoint returns a list of customers by points earned in descending order.
GET
GET /v2/top-earners/?business={business_id}
Example
Example Request
curl https://api.perkville.com/v2/top-earners/?business=4 -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "first_name": "John", "last_name": "Doe", "user_id": 544623, "last_earned_location_id": 2684, "home_location_id": 2684, "points_earned": 100, "connection_id": 767193, "primary_user_address": "john.doe@example.org" }
Restrictions
Required scopes:
- ADMIN_CUSTOMER_INFO
Pagination:
- A limit of 100 records is the most allowed for a single query.
Querystring Parameters
Name | Type | Required | Description |
business_id | integer | ✓ | The primary key of the business to run a report for. |
locations | integer[] | One or more location primary keys. User point totals will only include points earned at specified locations. | |
from_date | date | Beginning of report date range using format YYYY-MM-DD. | |
to_date | date | End of report date range using format YYYY-MM-DD. | |
hide_pending | boolean | Setting this parameter will exclude PENDING users. | |
hide_cancelled | boolean | Setting this parameter will exclude users without an ACTIVE connection to the business. |
Fields
Property Name | Type | Filterable | Description |
first_name | string | The user's first name. | |
last_name | string | The user's last name. | |
user_id | integer | The primary key of the User. | |
last_earned_location_id | integer | The primary key of the location where the user last earned points. | |
home_location_id | integer | The primary key of the user's home location. | |
points_earned | integer | The total number of points earned by the user during the report's date range. | |
connection_id | integer | The primary key of the connection resource referencing the user and business. | |
primary_email_address | string | The user's primary email address |
Transaction Report
This endpoind returns a list of transactions at a business.
The only difference between this endpoint and the and the Transaction Resource above is that this endpoint can be queried by business primary key without a user. If you only need to get transactions for a single user, the Transaction resource above should be preferred.
GET
GET /v2/transaction-report/?business={business_id}
Example
Example Request
curl "https://api.perkville.com/v2/transaction-report/?business=4" -H "Authorization: Bearer accesstoken123abc"
Example Response
{ "classification": "REDEEM", "title": "25% off next purchase", "trans_source_id": null, "perk_id": 461, "business_id": 5, "trans_status": "ACTIVE", "points": 300, "transaction_dt": "2021-09T04:54:12Z", "user_id": 1, "locations_id": 7, "transaction_id": 38000, "quantity": 1 }
Restrictions
Required Scopes
- ADMIN_CUSTOMER_INFO
Querystring Parameters
Name | Type | Required | Description |
business_id | integer | ✓ | The primary key of the business to get transactions for. |
locations | integer[] | One or more location primary keys can be used to only get transactions from specific locations. | |
from_datetime | datetime | Beginning of the query date range using the format YYYY-MM-DD HH:MM:SS (All values assumed to be in UTC) | |
to_datetime | datetime | Inclusive end of the query date range using the format YYYY-MM-DD HH:MM:SS (All values assumed to be in UTC) | |
limit | integer | Used for pagination. 5000 is the maximum value allowed. | |
offset | integer | Used for pagination. |
Fields
Property Name | Type | Filterable | Description |
classification | string | The classification of the perk tied to this transaction. Either "EARN" or "REDEEM", indicating if this rule is for receiving points or for spending. | |
title | string | The user-readable description of what this transaction was actually for. e.g., "Checkin" or "Free Hoodie" | |
trans_source_id | string | This field may be present if the transaction was created via an API. It is used to ensure that the transaction is unique at this business. | |
perk_id | int | The primary key of the perk in the transaction. | |
business_id | int | ✓ | The primary key of the business in the transaction. |
transaction_status | string | The current status of the Transaction. The options are ACTIVE, VOID, VOID_REF. When a transaction is voided two the things happen. The transaction gets updated with a status of VOID, and a new transaction, for the negative amount of the original transaction, is created with the status VOID_REF. The transaction_reference field described below will also be used in order for the original transaction to reference the transaction that voided it and vice versa. | |
points | int | The points that were either spent (REDEEM type perk) or earned (EARN type perk) with this transaction. | |
transaction_dt | datetime | ✓ | The date and time the transaction was created. |
user_id | int | The primary key of the user associated with the transaction. | |
transaction_reference | The primary key of the transaction referenced. | Certain types of transactions may be created in reference to another transaction. In those cases this field is used. | |
location_id | int | ✓ | The primary key of the location associated with the transaction. |
quantity | int | The quantity of the transaction -- usually this is used with the EARN transaction event for a dollar spent rule. |
Getting Started with Batch Endpoints
The following endpoints allow a staff member to post data in bulk to our API. While these endpoints are a part of APIv2, some of their basic functionality differs from the resources endpoints.
Resource URIs
Resource URIs are not supported. Only primary keys are used.
External Member Batch
Create/update external membership details in batch at a business. If an external member already exists, we'll update the record. If no external member detail exists for the provided external_member_id and external_system_id, we'll create the record. Limit of 50 can be posted at a time.
GET
POST
POST /v2/batch/external-members/
Example
Example Request
curl https://api.perkville.com/v2/batch/external-members/ -H "Authorization: Bearer accesstoken123abc" -H "Content-Type: application/json" -d '{"business": "1", "external_members": [{"home_location": "2","external_member_id": "1111111","external_system_id": "EXAMPLE_SOFTWARE","user_email": "john.doe@example.org","external_join_dt": "2018-05-02 12:35:00"},{"home_location": "2","external_member_id": "222222","external_system_id": "EXAMPLE_SOFTWARE","external_join_dt": "2018-05-02 12:35:00"}]}'
Example Response
{ 'business': '1', 'external_members': [ { "external_membership_status": null, "user_id": 263727, "resource_id": 3, "external_join_dt": "2018-05-02T12:35:00Z", "external_member_id": "1111111", "external_system_id": "EXAMPLE_SOFTWARE", "external_cancel_dt": null, "connection_id": 1, "home_location_id": 2, "external_membership_type": null }, { "error_type": "invalid_request_error", "errors": { "user_email": ["This field is required."] } } ] }
Restrictions
Required scopes:
- ADMIN_CUSTOMER_INFO
Parameters
Property Name | Type | Description |
business | int | The ID of the Business to which this external member belongs. |
external_members | list | A list of JSON objects containing external member information. See External Members Parameters below for more detail. |
External Member Parameters
Property Name | Type | Description |
user_email | string | The email of the user to which this external member belongs. |
external_member_id | string | The external identifier for this membership record |
external_system_id | string | A unique identifier representing the external system from which this member came. |
external_membership_type | string | OPTIONAL. The external member's membership type |
external_membership_status | string | OPTIONAL. The external member's membership status. Values include "ACTIVE", "INACTIVE", or null. |
home_location | int | OPTIONAL. The ID of the external member's home location. Include this OR the "external_home_location_id" parameter, but not both. |
external_home_location_id | string | OPTIONAL. The external_location_id of the Location you'd like to use for this external member's home location. Include this OR the "home_location" parameter, but not both. |
external_cancel_dt | datetime | OPTIONAL. The date and time a user's membership status converted from "ACTIVE" to "INACTIVE" |
external_join_dt | datetime | OPTIONAL. The date and time a user's membership became "ACTIVE" |
birthday | date | OPTIONAL. The user's birthday as "YYYY-MM-DD". If the user already exists, and does not have a birthday on file, we will update the user with the provided birthday. |
first_name | string | OPTIONAL. The user's first name. If the user already exists, and does not have a first name on file, we will update the user with the provided first name. |
last_name | string | OPTIONAL. The user's last name. If the user already exists, and does not have a last name on file, we will update the user with the provided last name. |
can_receive_emails | boolean | Indicates if we should send any emails to this user. Defaults to true if nothing is passed in. Please note that this parameter only applies to newly created users. If the user/email already exists, this parameter will be ignored. |
Returns
A 200 response with a list of JSON objects representing each external member create/update result. Results will be returned in the order they were given. If successful, the JSON object will include the created/update external member details. If unsuccessful, it will include an "errors" JSON object with detail about what went wrong. Please toggle the posted Example for a clear view of the behavior.
Transaction Batch
This accepts a list of transaction data for a given Business. Limit of 200 can be posted at a time.
GET
POST
POST /v2/batch/transactions/
Example
Example Request
curl https://api.perkville.com/v2/batch/transactions/ -H "Authorization: Bearer accesstoken123abc" -H "Content-Type: application/json" -d '{ "business": "1", "transactions": [{"location": "2", "perk": "397", "quantity": "1", "user_email": "edward_test@perkville.com", "first_name": "Edward", "last_name": "McFudge"}, {"location": "1", "perk": "397", "quantity": "1", "user_email": "rex_test@perkville.com", "first_name": "Rex", "last_name": "McJudge"}] }'
Example Response
{ 'business': '1', 'transactions': [ { 'classification': 'REDEEM', 'transaction_dt': '2015-01-30T23:54:04.147208+00:00', 'perk': '397', 'business': '1', 'transaction_status': 'ACTIVE', 'voucher': '552044', 'transaction_reference': null, 'location': '2', 'user': '263727', 'title': 'Free Hoodie', 'trans_source_id': null, 'points': 300, 'transaction_id': 3144, 'quantity': 1 }, { 'errors': { 'message': 'The user doesn't have enough points to complete this transaction.', 'code': 'pv_txn_insufficient_points' } } ] }
Restrictions
Required scopes:
- PUBLIC
- Both of these:
- ADMIN_CUSTOMER_GRANT_POINTS
- ADMIN_CUSTOMER_REDEEM
When creating batch Transactions, the following fields will apply to the entire batch:
- Business (required)
- Send email
- Voucher start as unused
- Business ID
- Location ID or External location ID
- Perk ID
- Quantity
- Trans source ID (Not technically required, but strongly recommended)
Parameters
Property Name | Type | Description |
business | int | The ID of the Business of this transaction |
send_email | boolean | This is an OPTIONAL parameter. Indicates if we should send an email to the user upon earning or redeeming. Defaults to true if nothing is passed in. Perks that the business has configured to not trigger an email will never do so regardless of the value of this parameter. |
voucher_start_as_unused | boolean | This is an OPTIONAL parameter. If this is true AND the perk is redeem-type perk, the user's voucher will be created in a UNUSED status. This defaults to false, as normally perks redeemed by admins on a user's behalf are marked as USED. |
limit_to_once_per_calendar_day | boolean | This is an OPTIONAL parameter. Defaults to false. If this is true, each user may only earn once per day for each perk, based on the timezone of the location. NOTE - This parameter will apply to the entire batch of transactions. If you do not want this rule to apply to ALL transactions in the batch, you will want to split up your API calls to reflect this. |
transactions | list | A list of JSON objects containing transaction information. See Transaction Parameters below for more detail. |
Transaction Parameters
Property Name | Type | Description |
location | int | The ID of the Location of this transaction. Include this OR the "external_location_id" parameter, but not both. PLEASE NOTE When creating redeem transactions for perks using the must_redeem_at_home_location option, the user's home location MUST be used. A user's home location can be found using the Connection resource. |
external_location_id | string | The external_location_id of the Location you'd like to use for this transaction. Include this OR the "location" parameter, but not both. |
perk | int | The ID of the Perk of this transaction |
quantity | int | The quantity of the transaction -- usually this is used with the EARN transaction event for a dollar spent rule. Not typically used with a REDEEM type perk. |
trans_source_id | string | This is an OPTIONAL parameter. This field is guaranteed to be unique for a business. API clients may use this field to ensure that the posted transaction is unique. For example, imagine an API client is awarding points for a customer's purchase. It may be a good idea to pass in the ID of the purchase into this field, avoiding the case where a customer may be awarded points twice for a purchase. Limit 128 characters. |
transaction_dt | datetime | This is an OPTIONAL parameter. It defaults to the current datetime. If passed in, we'll set the transaction_dt of the transaction to this value. This can be useful if posting transactions that occurred sometime in the past. This value may not be in the future, or more than 1 year in the past. This value must be in UTC! The following formats are valid -- '%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d' |
user_email | string | This is an OPTIONAL parameter. Include this or "user" but not both. If this user_email record exists in our database, we'll apply the transaction to that user. Otherwise, we'll create a new user with the passed user_email, first_name, and last_name. |
user | user | The ID of the User of this transaction. This is an OPTIONAL parameter. Include this or "user_email" but not both. |
first_name | string | Only include if you're using user_email instead of user. If this user_email record exists in our database, we'll apply the transaction to that user. Otherwise, we'll create a new user with the passed user_email, first_name, and last_name. |
last_name | string | Only include if you're using user_email instead of user. If this user_email record exists in our database, we'll apply the transaction to that user. Otherwise, we'll create a new user with the passed user_email, first_name, and last_name. |
external_member_id | string | This is an OPTIONAL parameter. This can serve as a separate identifier for a User. If included, this external_member_id will be used to identify the User. If the external_member_id does not already exist, then it will become associated with user/user_email passed into the request. |
external_system_id | string | This is an OPTIONAL parameter, however must be included when using the external_member_id parameter. This is used to identify the external membership system. So if the membership system is something like "Example Software", you could use "EXAMPLE_SOFTWARE" as the ID |
Returns
A 200 response with a list of JSON objects representing each transaction's result. Results will be returned in the order they were given. If successful, the JSON object will include the created transaction details. If unsuccessful, it will include an "errors" JSON object with detail about what went wrong. Please toggle the posted Example for a clear view of the behavior.
Using the Identify User Flow
The flow can be implemented by an API client in order to identify the Perkville user who is consuming the content of their application. The user must first be redirected to Perkville, where we authenticate the user, after which we redirect back to the clients app with a "code" URL parameter that can be used to retrieve user details from our API.
How is this different from the OAuth 2.0 Auth Code flow?
It is similar to the OAuth 2.0 flow, but not quite the same. One difference is that the user is not asked for permission in order for the client to access their data. As a result, the Identify User Flow can only be implemented by an API client using a bearer token for an admin staff user, which can already view details of users who are customers at their employer's business.
Note about Bearer Tokens
Bearer tokens allow an API client to make requests on behalf of a user and this flow does not change that fact. A bearer token issued for a staff member, with the necessary scopes, allows an API client to view customer details. The Identify User Flow adds to this functionality by allowing a client to identify a user, who is a customer at a business where bearer token user is employed, via a redirect through our service.
The Identify User Flow does not issue a new bearer token, and cannot be used to perform actions on behalf of the user who has been identified.
Acceptable Use
The necessary scope to implement this flow is not granted to API clients by default. If you'd like to implement this flow in your application you must contact us as api@perkville.com and describe your use-case in order to obtain permission.
An example of an acceptable use case would be if you manage a website for users of a Perkville rewards program, and you want to identify the person making a request to your site without forcing them to create a separate account to log in. The Identify User Flow would enable you to discover the identity of the person so that they can be logged in to your application in an unobstrusive manner.
Step 1
The first step is to request a token from the Identify Token endpoint documented below.
Identify Token
This endpoint allows an application to generate a single-use short-lived Identify Token. This token will then be used in the subsequent steps of the identify user flow, to know which Perkville user is consuming the application's content.
This endpoint is for identification purposes only. The token returned is not a bearer token and cannot be used for any purposes other than to initiate this specific flow. The token returned is valid for 30 mintues from the time it's created and invalid after it's used.
Do NOT JSON-encode the POST body. Encode the request body as application/x-www-form-urlencoded, which looks just like a querystring. See the example below.
GET
POST
POST https://api.perkville.com/v2/identify/
Example
Example Request
curl https://www.perkville.com/api/identify/ -H "Authorization: Bearer ryYMKAkopdwNb82FJTmxJ31L7T6K8z" -d "redirect_uri=https%3A%2F%2Fwww.example.org%2Foauth_callback%2F&state=dsgjndsguh3408fds"
Example Response
{ "expire_datetime": "2021-09-10T02:07:35.512Z", "identify_token": "9YAxyxXT5vrL3gIXGGTvMxh11FzdoQ" }
Restrictions
Required scopes:
- ADMIN_IDENTIFY_USER
Both of the following parameters are required for a valid POST request.
Parameters
Property Name | Type | Description |
redirect_uri | string | The uri where you would like Perkville to redirect the user once we have identified who they are. This MUST match one of the redirect uris that was provided upon client registration. |
state | string | A random hash generated by your application. When Perkville redirects back to the client server, this state value will be included in the redirect request query string so that the client servers can verify the authenticity of the request. |
Returns
A 201 Created response with the newly created Identify Token and it's time of expiration as JSON.
Step 2
Now that your application has obtained an identify token, the next step is to redirect the user to Perkville with that token.
Redirect the user to a business specific identify url along with the identify token as a querystring parameter. This will be the business's profile url with `identify` as the path. Here are a couple examples.
GET https://www.perkville.com/biz/5/identify?token=1234 GET https://mybiz.perkville.com/identify?token=1234
At this point if the user is not logged in to Perkville, they will be required to do so on the business's branded login page.
If they are already logged in, or once they log in, we'll validate the request. The request must include a `token` parameter. The user associated with the request must be connected to the business. The bearer token used to generate the token must be active and associated with a user who is an admin staff at the business. The bearer token must also have the necessary scopes described above. If any of these validations doesn't pass, we'll redirect the user to another profile page and display a generic error message.
Once the request is validated, the user will be redirected to the url specified in Step 1. The the redirect url will include `code` and `state` parameters. The `code` value is the identitification code. The `state` value should be the same value from Step 1. This is how you can validate that the request can from us. The identify token will be deleted at this time and will no longer be valid. If you want to know the identity of another user, you must generate another identify token. You application should expect to receive a request like the following example which assumes your redirect uri is https://example.com/callback/.
GET https://example.com/callback?code=abc123&state=xyz987
Step 3
Afer you have received the identification code you can use the standard User Resource in order to look up the details of the user. Bearer token users with the appropriate scopes can use a `code` parameter with that resource. See the following example.
GET /v2/users?code=abc123
Identification codes expire 30 secords after creation. This should be more than enough time for your application make a request to this resource after receiving the code.
See the User Resource docs for more information on what type of response to expect.