NAV Navbar
php
  • Introduction
  • Authentication with OAuth2
  • Authentication without OAuth2
  • Basics
  • Campaigns
  • Campaign Private Tokens
  • Leads
  • Pagination
  • Limits
  • Scopes
  • Errors
  • Introduction

    Welcome to the Scratcher API! Here you can see a list of all the resources we offer and a code example of how to access it.

    There is also a guide on how to authenticate with OAuth2.

    The PHP examples makes use of the Guzzle HTTP libary to make requests.

    Authentication with OAuth2

    To make use of our API you must use OAuth2. Scratcher expects all API requests to contain a header like so:

    Authorization: Bearer ACCESS_TOKEN

    Redirecting For Authorization

    <?php
    
    $query = http_build_query([
      'client_id' => 'client-id',
      'redirect_uri' => 'http://example.com/callback',
      'response_type' => 'code',
      'scope' => 'read:campaigns read:leads',
    ]);
    
    header('Location: ' . 'https://app.scratcher.io/oauth/authorize?' . $query);
    

    Remember to replace the parameters with your own.

    The first thing you have to do is redirect your user to the specified URL with the parameters below.

    If the parameters are valid the user will be shown a page where they can approve or deny access.

    Query Parameters

    Parameter Required Description
    client_id true The client id - this is found when creating an app on Scratcher
    redirect_uri true The redirect uri. This MUST match the redirect uri you specified when creating the app
    response_type true This must be "code"
    scope true The scopes your app needs

    Approving The Request

    A user must approve the request before he is redirected. If the user accepts, the user is redirected to your redirect_uri with the following parameters

    Parameter Description
    code An authorization code needed to get the access token

    If the user denies the request, the user is redirected to your redirect_uri with the following parameters

    Parameter Description
    error The error code. This defaults to access_denied

    Converting Authorization Codes To Access Tokens

    In this example, we make use of the Guzzle HTTP library to make the POST request

    <?php 
    $http = new GuzzleHttp\Client;
    
    $response = $http->post('https://app.scratcher.io/oauth/token', [
      'form_params' => [
        'grant_type' => 'authorization_code',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'redirect_uri' => 'http://example.com/callback',
        'code' => 'YOUR_CODE_HERE',
      ],
    ]);
    
    return json_decode((string) $response->getBody(), true);
    

    The above request returns the following JSON:

    {
      "token_type": "Bearer",
      "access_token" : "...",
      "refresh_token" : "...",
      "expires_in" : 31536000
    }
    

    If the user approves the authorization request, they will be redirected back to your application. You should then issue a POST request to our application to request an access token. The request should include the authorization code that was issued by our application when the user approved the authorization request.

    Parameters

    Parameter Required Description
    grant_type true
    client_id true The client id - this is found when creating an app on Scratcher
    client_secret true The client secret - this is found when creating an app on Scratcher
    redirect_uri true The redirect uri. This MUST match the uri specified on the app
    code true The code received from the redirect

    This /oauth/token route will return a JSON response containing token_type, access_token, refresh_token, and expires_in attributes.

    Access tokens expire after 1 year and refresh tokens expire after 1 year and 2 week.

    Refreshing Access Tokens

    <?php
    
    $http = new GuzzleHttp\Client;
    
    $response = $http->post('https://app.scratcher.io/oauth/token', [
        'form_params' => [
            'grant_type' => 'refresh_token',
            'refresh_token' => 'your-refresh-token',
            'client_id' => 'client-id',
            'client_secret' => 'client-secret',
            'scope' => 'read:campaigns read:leads',
        ],
    ]);
    
    return json_decode((string) $response->getBody(), true);
    

    The above request returns the following JSON:

    {
      "token_type": "Bearer",
      "access_token" : "...",
      "refresh_token" : "...",
      "expires_in" : 31536000
    }
    

    You will need to refresh the access token after 1 year.

    To refresh the access token, make a request to our server with the refresh_token.

    Parameters

    Parameter Required Description
    grant_type true
    refresh_token true The refresh token you got when first authenticating using OAuth2
    client_id true The client id - this is found when creating an app on Scratcher
    client_secret true The client secret - this is found when creating an app on Scratcher
    scope true The scopes your app needs

    Authentication without OAuth2

    We recommend using OAuth2 to authorize but you can also create an infinite-lived access token under your account on Scratcher. You can then use the token as you would use an OAuth2 token.

    Basics

    This contains the basic routes such as /me

    Account information

    Remember to replace the $accessToken with your own.

    <?php
    
    $http = new GuzzleHttp\Client;
    
    $client->request('GET', 'https://app.scratcher.io/api/v1/me', [
        'headers' => [
            'Accept' => 'application/json',
            'Authorization' => 'Bearer ' . $accessToken,
        ],
    ]);
    

    This returns the following response in JSON

    {
        "data": {
            "id": 1,
            "name": "John Doe",
            "company_name": "Johnny Cars A/S",
            "email": "john@example.com",
            "phone": 88888888,
            "address_street": "Fakestreet 1",
            "address_zipcode": "0000",
            "address_city": "Fake City",
            "cvr": "00000000"
        }
    }
    

    In this example, we make use of the Guzzle HTTP library to make the GET request to fetch the authenticated user's information.

    HTTP Request

    GET https://app.scratcher.io/api/v1/me

    Campaigns

    List campaigns

    Remember to set the headers and access token

    <?php
    
    $http = new GuzzleHttp\Client;
    
    $client->request('GET', 'https://app.scratcher.io/api/v1/campaigns');
    

    Response:

    {
        "data": [
            {
                "id": 1,
                "name": "My Campaign",
                "url_slug": "my-campaign",
                "url": "https://game.scratcher.io/my-campaign",
                "demo_url": "https://game.scratcher.io/my-campaign?dt=foobar",
                "start_date": "2018-01-01 12:00:00",
                "end_date": "2018-01-02 12:00:00",
                "active": false,
                "ended": true,
                "created_at": "2017-12-30 23:59:00"
            }
        ]
    }
    

    This will list all your campaigns ordered by their creation date. This is paginated with 10 campaigns per page.

    HTTP Request

    GET https://app.scratcher.io/api/v1/campaigns

    Query Parameters

    Parameter Required Default Description
    page false 1 The page to fetch data from
    query false null Specify this to filter campaigns by name

    Campaign Private Tokens

    Campaign private tokens are used to access private campaigns. The tokens have a length of 64 characters.

    Create private token

    Remember to set the headers and access token

    <?php
    
    $http = new GuzzleHttp\Client;
    
    $client->request('POST', 'https://app.scratcher.io/api/v1/campaigns/{campaignId}/private-tokens');
    

    Response:

    {
        "data": {
            "id": 1,
            "token": "81f144fcf56cbd32e4e612fc4590aab9bac8141cb833104549f4e0788882fe3e",
            "campaign_url": "https://game.scratcher.io/foobar?token=81f144fcf56cbd32e4e612fc4590aab9bac8141cb833104549f4e0788882fe3e",
            "created_at": "2017-12-30 23:59:00"
        }
    }
    

    This will create a new token for accessing the specified campaign. This token is a one-time use which means you should generate a token for each visitor/user/participant.

    HTTP Request

    POST https://app.scratcher.io/api/v1/campaigns/{campaignId}/private-tokens

    Error responses

    If the campaign is not private, or if the campaign has ended you will receive a 400 response code.

    Key Description
    error The reason for the error

    Leads

    List leads

    <?php
    
    $http = new GuzzleHttp\Client;
    
    $client->request('GET', 'https://app.scratcher.io/api/v1/campaigns/{campaignId}/leads');
    

    Response:

    {
        "data": [
            {
                "id": 1,
                "first_name": "John",
                "last_name": "Doe",
                "email": "john@example.com",
                "phone_number": "88888888",
                "ip_address": "127.0.0.1",
                "prize": {
                    "id": 1,
                    "name": "50% Discount Code",
                    "description": "...",
                },
                "draw_prize": null,
                "created_at": "2017-12-30 23:59:00",
                "custom_fields": [
                    {
                        "field_name": "zipcode",
                        "value": "8800"
                    }
                ]
            }
        ]
    }
    

    This will list all the leads on the specified campaign ordered by their creation date. This is paginated with 20 leads per page.

    HTTP Request

    GET https://app.scratcher.io/api/v1/campaigns/{campaignId}/leads

    Query Parameters

    Parameter Required Default Description
    page false 1 The page to fetch data from

    Prize

    There a two prize fields: prize and draw_prize. prize is set if the lead won a prize, and draw_prize if the lead won the draw prize.

    A prize field contains the following fields:

    Field Type Description
    id integer The ID of the prize
    name string The name of the prize
    description string The description of the prize

    Custom fields

    This contains any or all custom fields that are on the lead. These usually comes from the campaign the lead registered on.

    Pagination

    Example of paginated JSON response

    {
        "data" [],
        "links": {
            "first": "https://app.scratcher.io/api/v1/{RESOURCE_URL}?page=1",
            "last": "https://app.scratcher.io/api/v1/{RESOURCE_URL}?page=5",
            "prev": "https://app.scratcher.io/api/v1/{RESOURCE_URL}?page=1",
            "next": "https://app.scratcher.io/api/v1/{RESOURCE_URL}?page=3"
        },
        "meta": {
            "current_page": 2,
            "from": 21,
            "last_page": 5,
            "path": "https://app.scratcher.io/api/v1/{RESOURCE_URL}",
            "per_page": 20,
            "to": 40,
            "total": 100
        }
    }
    

    Most resources are paginated. Every paginated resource contains 2 extra fields in the response. See example to the right.

    Links

    This contains the links for the first, last, previous and next page.

    Meta

    This contains meta-information regarding what page you are on, how many entries per page, the total count, etc.

    Limits

    Rate Limits

    Response:

    {
        "message": "Too Many Attempts."
    }
    

    We have a rate limit of 60 requests per minute before you are throttled. If you make a request while throttled you receive a 429 response.

    Headers

    Name Description
    X-RateLimit-Limit The limit per minute
    X-RateLimit-Remaining The amount of remaining attempts before you are throttled
    X-RateLimit-Reset The unix timestamp for when you can retry
    Retry-After The amount of seconds until you can retry

    Scopes

    The following scopes are available.

    Scope Description
    read:campaigns Allow listing all campaigns
    read:leads Allow listing leads on campaigns

    Errors

    The scratcher API uses the following error codes:

    Error Code Meaning
    400 Bad Request -- Your request is invalid.
    401 Unauthorized -- Your API key is wrong.
    403 Forbidden -- You do not have the scopes required to access this OR you do not have access to this resource.
    404 Not Found
    405 Method Not Allowed -- The method you used was invalid.
    410 Gone -- The requested resource has been removed from our servers.
    429 Too Many Requests
    500 Internal Server Error -- We had a problem with our server. Try again later.
    503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.
    php