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

    You can retrieve a specific campaign as well as list all the campaigns on your account.

    The campaign object

    The campaign object

    {
        "id": 1337,
        "name": "Easter campaign 2019",
        "url_slug": "easter-campaign-2019",
        "url": "https://game.scratcher.io/easter-campaign-2019",
        "demo_url": "https://game.scratcher.io/easter-campaign-2019?dt=362d0b21-865c-4c6e-9799-fdc993f72b92",
        "start_date": "2019-04-14 12:00:00",
        "end_date": "2019-04-22 12:00:00",
        "active": true,
        "ended": false,
        "created_at": "2019-03-15 11:57:34"
    }
    

    Attributes

    id
    integer
    Unique identifier for this object
    name
    string
    The name of the campaign
    url_slug
    string
    URL-slug used for accessing the campaign
    url
    string
    URL to the live-page of the campaign
    demo_url
    string
    URL to the demo page of the campaign
    start_date
    datetime string
    Start date of the campaign
    end_date
    datetime string
    End date of the campaign
    active
    boolean
    This boolean represents if the campaign is active
    ended
    boolean
    This boolean represents if the campaign has ended
    created_at
    datetime string
    Datetime at which this object was created

    Retrieve a campaign

    Remember to set the headers and access token

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

    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 show the information for the specified campaign

    HTTP Request

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

    List all 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 a 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/:id/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/:id/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

    The lead object

    The lead object

    {
        "id": 1,
        "first_name": "John",
        "last_name": "Doe",
        "email": "john@example.com",
        "phone_number": "88888888",
        "ip_address": "127.0.0.1",
        "prize": {
            "id": 36,
            "name": "50% Discount Code",
            "description": "...",
        },
        "draw_prize": {
            "id": 252,
            "name": "$1.000 coupon",
            "description": "Lorem ipsum dolor sit amet",
        },
        "created_at": "2017-12-30 23:59:00",
        "custom_fields": [
            {
                "field_name": "zipcode",
                "value": "8800"
            }
        ]
    }
    

    Attributes

    id
    integer
    Unique identifier for this object
    first_name
    string
    The first name of the lead
    last_name
    string
    The last name of the lead
    email
    string
    The email of the lead
    phone_number
    string
    The phone number of the lead
    ip_address
    string
    The IP adresse of the lead
    created_at
    datetime string
    Datetime at which the object was created
    prize
    object

    The prize that the lead has won

    Show child attributes

    prize.id integer

    Unique identifier for this object

    prize.name string

    The name of the prize

    prize.description string

    Description of the prize

    draw_prize
    object

    The draw prize that the lead has won

    Show child attributes

    draw_prize.id integer

    Unique identifier for this object

    draw_prize.name string

    The name of the prize

    draw_prize.description string

    Description of the prize

    custom_fields
    array

    An array of all the custom fields of the lead

    Show child attributes

    custom_fields[:index].field_name string

    The name of the field

    custom_fields[:index].value string

    The value of the field

    List all leads

    <?php
    
    $http = new GuzzleHttp\Client;
    
    $client->request('GET', 'https://app.scratcher.io/api/v1/campaigns/:id/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/:id/leads

    Query Parameters

    Parameter Required Default Description
    page false 1 The page to fetch data from
    sort false N/A The column to sort by

    Sorting

    You can sort the leads by specifying the sort query parameter.
    The following columns are sortable: id, created_at, updated_at.

    If you prefix the column with a - it is sorted by descending.

    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