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.

Register

Authentication

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.

OAuth2 Authorization

The official OAuth2 specification includes several different methods of acquiring an access token. We support the following:

Authorization Code Grant

Put simply, this flow works as follows: You redirect a user to Perkville. The user gives us permission to let you see and manipulate their data. We redirect back to your application with a short-lived access token. Finally, you make a separate call to Perkville in which you exchange the short-lived token for a long-term bearer token.

PKCE extension

We also support the PKCE extension for the authorization code grant flow. When implementing PKCE, before performing Step 1, the client first creates what are knows as the "code verifier" and the "code challenge" values. A succinct description of how to generate these values, and the PKCE flow in general can be found in the following docs. https://www.oauth.com/oauth2-servers/pkce/authorization-request/

Step 1

Redirect the user to our OAuth2 authorization URL with the querystring parameters listed below. Our OAuth2 authorization URL is the following:

https://www.perkville.com/api/authorize/
key required description
client_id Yes The client id that was emailed to the developer contact upon client registration
redirect_uri No The redirect uri that you would like Perkville to redirect your user to once they have authorized your application to access their data on Perkville. Important: This MUST match one of the redirect uris that was provided upon client registration. If this querystring parameter is omitted, Perkville will default to the first redirect uri it has stored for the provided client id.
response_type Yes This must be "code" for the authorization code flow.
scope No The scopes that you would like to request access to on behalf of the user, separated by spaces. See below for a detailed explanation of the allowed scopes. If not provided, defaults to all of the scopes that your client application is allowed to request.
state No It is recommended that the client application populate this query parameter with a random hash. When Perkville redirects the user back to the client server, this state will be included in the redirect request query string so that the client servers may verify the authenticity of the request.
code_challenge
( PKCE )
No The code challenge value generated for use in the PKCE flow.
code_challenge_method
( PKCE )
No This should be S256. While the PKCE flow spec allows both "S256" and "plain" as valid challenge methods, our application only supports S256 at this time.
For example, the URL that you redirect a user to may look like the following:
https://www.perkville.com/api/authorize/?scope=PUBLIC+USER_CUSTOMER_INFO+USER_REDEEM&state=dsgjndsguh3408fds&redirect_uri=https%3A%2F%2Fwww.example.org%2Foauth_callback%2F&response_type=code&client_id=123myclientid&response_type=code

Step 2

Once the user has been redirected to the Perkville servers, they will be asked to login. Then, the user will be shown a page which summarizes what actions the API client has access to, and asks the user to agree. Upon agreement, our servers generate an authorization code which we will include in a querystring and attach to the redirect uri that was specified in step 1. The user will then be redirected back to this uri, and the client servers may then grab this authorization code and proceed to step 3.

Following from the example request in step 1, The URL that perkville will redirect the user back to may look like the following:

https://www.example.org/oauth_callback/?code=ylisfw49snfnsdaa&state=dsgjndsguh3408fds

Step 3

Now that your application has an authorization code, you can use it to request an access token. Access tokens can be requested by POSTing to the access token URL listed below with the following POST body. Important: This step must be initiated within 5 minutes after the redirect to your application in step 2 above. 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.

https://www.perkville.com/api/token/
key required description
client_id Yes The client id of the consuming application.
client_secret No* The client secret of the consuming application.
* Include the secret here as a GET parameter, or in a Basic Auth header (described below).
code Yes The authorization code that was given to the application in step 2.
grant_type Yes The type of grant that's being requested. This should be "authorization_code".
redirect_uri Yes This is the redirect_uri that was provided in step 1.
state No If a state was provided in step 1, you must provide the state again in this request.
code_verifier
( PKCE )
No The code verifier that was generated along with the code challenge if one was sent in Step 1.

Client secret:

  • Clients implementing the PKCE Mobile Grant flow should not use the client secret at all.
  • Instead of passing in the client_secret as a GET parameter, the request may include it as a Basic Auth header. The username/password for the basic authentication request must be the client id/secret.

Following from the above examples, here is what an example request may look like using curl:
curl https://www.perkville.com/api/token/ -d "code=ylisfw49snfnsdaa&grant_type=authorization_code&redirect_uri=https%3A%2F%2Fwww.example.org%2Foauth_callback%2F&state=dsgjndsguh3408fds&client_id=123myclientid" -u 123myclientid:myclientpassword

If successful, Perkville will respond with an access_token and the scopes that are applicable to the access token. The returned access token should be used to request v2 resources listed below. See "Accessing Endpoints" for more information on how to access resources.

PKCE Mobile Grant

The PKCE mobile grant flow is similar to the Authorization Code Grant flow with the PKCE extension, except that the client secret should not be used, nor should the basic auth header.

This flow is intended to be used by mobile applications since they cannot keep the client secret value confidential. Whereas clients having the Authorization Code grant may optionally implement the PKCE extension for added security, clients having only the PKCE Mobile grant must implement this version of the PKCE flow.

Resource Owner Password Credentials Grant

This is much simpler than the 3-legged Authorization Code grant flow. In this flow, you will simply ask the Perkville user for their username and password. Then, you make ONE request to Perkville's API with the username and password. We will respond with an access token that does not expire, which you will use to make all subsequent API requests. Store the access token. Do not store the user's username or password.

Use Cases

The only acceptable use case is performing administrative tasks (like awarding points) on behalf of a single administrator's account. Developers will be approved to use this grant type on a case by case basis.

All other use cases are inappropriate. An example of an inappropriate use case would be a website which collects a regular user's username and password and then provides the user a custom interface for redeeming points. In this case, instead of using the password grant type, the 3-legged authorization code type should be used.

If you are unsure of which grant type to use, we're here to help. Email us at api@perkville.com.

Appropriate Usage

DO NOT store the username and password.

Examples of inappropriate usage include: Storing the password in source code. Storing the password in any database of any type, anywhere, at any time, except for the few moments needed to create an access token.

Password Grant Flow

After collecting the username and password, make the following request to our API: Do NOT JSON-encode the POST body. Encode the JSON body as application/x-www-form-urlencoded, which looks just like a querystring. See the example below.

https://www.perkville.com/api/token/
key required description
grant_type Yes The type of grant that's being requested. This should be "password".
username Yes This should be the user's Perkville username.
password Yes This should be the user's Perkville password.
In addition, the request must define the "Authorization" header for basic authentication. The username/password for the basic authentication request must be the client id/secret. Following from the above examples, here is what an example request may look like using curl:
curl https://www.perkville.com/api/token -d "grant_type=password&username=hello@perkville.com&password=password&client_id=123myclientid" -u 123myclientid:myclientpassword
If successful, Perkville will respond with an access_token and the scopes that are applicable to the access token. The returned access token should be used to request v2 resources listed below. See "Accessing Endpoints" for more information on how to access resources.

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=1234
This 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_BONUS
This 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%3A00Z
The 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=REDEEM
The 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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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', or 'EMAIL_ONLY'.
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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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": [],
    "locations": [
        "/v2/locations/1/"
    ],
    "name": "Push Up Challenge",
    "resource_uri": "/v2/challenges/5/",
    "slug": "push-up-challenge",
    "start_date": "2020-06-21",
    "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.
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.
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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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",
    "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/"
},
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
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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

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
Include only valid JSON in your HTTP body.
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

You can't delete this resource

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
Include only valid JSON in your HTTP body.
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

You can't update this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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
Include only valid JSON in your HTTP body.
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
Include only valid JSON in your HTTP body.
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

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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
Include only valid JSON in your HTTP body.
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
Include only valid JSON in your HTTP body.
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

You can't delete this resource

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/",
    "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.
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/",
    "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
Include only valid JSON in your HTTP body.
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/",
    "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
Include only valid JSON in your HTTP body.
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

You can't delete this resource

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 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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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
Include only valid JSON in your HTTP body.
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

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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)
We STRONGLY recommend using a trans_source_id. This will ensure that the same event will never be awarded twice, like if you post older events to backfill data. It also greatly helps in debugging, as we can point to the exact event ID from your application that created this Transaction.

For identifying whom should receive this Transaction, there are a few options:

  • User URI
  • User email
  • External member ID and External system ID
If the User exists, we'll simply add that Transaction for that User. If the User doesn't exist, we'll create a new user from the provided email, award the Transaction, and then send the user an invitational email.

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
Include only valid JSON in your HTTP body.
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

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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.
email 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

You can't create new instances of this resource

PATCH

You can't update this resource

DELETE

You can't delete this resource

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

You can't create new instances of this resource

PATCH

This endpoint allows you to change the status and expiration date of vouchers.
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
Include only valid JSON in your HTTP body.
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

You can't delete this resource

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",
                    "to_date": "2023-05-31"
                }
            ],
            "description": "",
            "display_name": "Check-in",
            "display_order": null,
            "frequency_bonuses": [
                {
                    "bonus_points": 200,
                    "earned_count": 0,
                    "frequency": "FROM_DATE",
                    "required_to_earn": 5,
                    "start_date": "2021-01-01"
                }
            ],
            "loc_id": 1,
            "perk_id": 246,
            "points": 2,
            "time_bonuses": [
                {
                    "multiplier": "2.00",
                    "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.
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} 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.
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 is 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.

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.
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.

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

You can't read from this resource.

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
Include only valid JSON in your HTTP body.
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
Include only valid JSON in your HTTP body.
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

You can't read from this resource.

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
For each transaction in the 'transactions' list 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)
Parameters
Include only valid JSON in your HTTP body.
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
Include only valid JSON in your HTTP body.
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

You can't read from this resource.

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.