OAuth 2.0

The seven.io API can be used for authentication and authorization using the OAuth 2.0 protocol to allow users of your software to easily and directly integrate our service.

Basics

OAuth 2.0 allows your application to gain access rights to customer accounts in order to send API requests directly to us on their behalf.

To do this, you must first register your application with us. You do this yourself in the dashboard under Developer > OAuth apps. There you set the name, the redirect URL (redirect_uri) and the scopes you need, and you receive client_id and client_secret as your access data to our OAuth 2.0 API.

The client_secret is shown only once, right after creation, and we only store a hash of it. Keep it somewhere safe. If you lose it, you can generate a new one in the dashboard, which invalidates the old one.

All applications now run according to the following pattern when accessing our API with OAuth 2.0:

  • First, you must obtain authorization from the customer. To do this, you redirect the customer to a special page on our site, where the customer must log in and grant your application access.
  • After confirming or rejecting the authorization request, the customer is sent back to your application. If the customer grants authorization, your application will receive an authorization code.
  • With this authorization code, your application can retrieve the access token via our OAuth 2.0 API, which enables direct access to our APIs.

Access tokens have a limited lifetime of one hour by default. If your application requires access to our APIs beyond the lifetime of a single access token, it can retrieve new access tokens using the refresh token.


Process

  1. 1

    Set up application

    When you create the app in the dashboard, you receive the following access data:

    • Name
      client_id
      Type
      string
      Description

      Your access ID. Self-created apps get a random ID in the form app_.... The examples on this page use testclient for readability.

    • Name
      client_secret
      Type
      string
      Description

      Access password for the OAuth2.0 API. Shown only once, when the app is created. In the example here, this is testsecret.

    In addition, you set a redirect_uri to which we will redirect after authorization. In our example here, the URL is https://acme.inc/oauth_redirect. Several redirect URLs are possible - the one passed in the authorization request must match one of them exactly.

  2. 2

    Redirect customer to OAuth 2.0 authorization page

    Forward your customers to the following URL:

    https://oauth.seven.io/authorize?response_type=code&client_id=testclient&state=xyz&scope=sms%20analytics

    • Name
      state
      Type
      string
      Description

      A randomly generated string and to prevent CSRF attacks. Please use a cryptographically secure string for this purpose.

    • Name
      scope
      Type
      string
      Description

      The requested scope to which you would like to have access - in this case the sending of SMS and the retrieval of statistics. Multiple scopes can be passed separated by spaces.

  3. 3

    Customer is sent back to your application

    After the customer has granted (or denied) authorization, we automatically redirect them to your redirect_uri with some additional GET parameters.

    If successful:

    https://acme.inc/oauth_redirect?code=9ccb478a7cbe043c1df211f1d52a6437f8756cf8&state=xyz

    In case of error:

    https://acme.inc/oauth_redirect?error=access_denied&error_description=The+user+denied+access+to+your+application&state=xyz

    You should always check here whether state corresponds to the value you created in the second step in order to avoid CSRF.

  4. 4

    Query access token

    Retrieve the access token and the refresh token via our OAuth 2.0 API.


POST/token

Retrieve access token

If everything has worked up to this point, you can now use the GET parameter code from step 3. to retrieve an access token as follows:

Request

curl -u testclient:testsecret https://oauth.seven.io/token \
  -d 'grant_type=authorization_code&code=9ccb478a7cbe043c1df211f1d52a6437f8756cf8'

If successful, you will receive data in JSON format as follows:

Response

{
  "access_token":"b1a9391d0469cafe30258893ab6025d4ad94ecec",
  "expires_in":3600,
  "token_type": "Bearer",
  "scope": "sms",
  "refresh_token":"ffd8e622aa5dccc2905f2ac6a0999c785a803157"
}

POST/token

Update access token

To update the access token, call the OAuth 2.0 API as follows:

Request

curl -u testclient:testsecret https://oauth.seven.io/token \
  -d 'grant_type=refresh_token&refresh_token=ffd8e622aa5dccc2905f2ac6a0999c785a803157'

If successful, you will receive new token data in JSON format as follows:

Response

{
  "access_token": "worw5xlrl0sjwqkvmstibwn4pw0mdvpddljzkfi8",
  "expires_in":3600,
  "token_type": "Bearer",
  "scope": "sms",
  "refresh_token": "n94c2kyej8ycsjutmviuk8i6zebgsda0uzg2gbpn"
}

POST/revoke

Revoke token

To revoke an access token or refresh token, call the OAuth 2.0 API as follows:

Request

curl -u testclient:testsecret https://oauth.seven.io/revoke \
  -d "token=b1a9391d0469cafe30258893ab6025d4ad94ecec"
  • Name
    token
    Type
    string
    Description

    The access token or refresh token to be revoked.

  • Name
    token_type_hint
    Type
    string
    Optional
    Optional
    Description

    A hint about the type of the token: access_token or refresh_token. This helps the server to find the token faster.

If successful, you will receive a response in JSON format as follows:

Response

{
  "revoked": true
}

In case of an error, the server responds with HTTP status code 400:

Error Response

{
  "error": "invalid_client",
  "error_description": "The client credentials are invalid"
}

Note: For security reasons, the server will respond with a 200 OK even if the token was already invalid or belongs to a different client.


Access to our APIs

Call our APIs according to the respective documentation and send the access token in the Authorization Header without further encoding (no base64 or similar).

curl https://gateway.seven.io/api/sms -H 'Authorization: Bearer ACCESS_TOKEN'

You can also test the successful connection via OAuth 2.0 using the following call:

Request

curl https://oauth.seven.io/me -H 'Authorization: Bearer ACCESS_TOKEN'

Response

{
    "success": true,
    "user_id": 12345,
    "email": "john.doe@acme.inc",
    "company": "Acme Inc.",
    "alias": "acme_inc",
    "balance": "627.3615"
}

Scopes

The following scopes of application can be requested by the customer:

ScopeMeaning
analyticsQuery statistics
balanceQuery credit balance
contactsQuery and edit contacts
groupsQuery and edit groups
hooksAllows you to change and view webhooks
journalQuery your logbook
lookupExecute requests via lookup (HLR, MNP etc.)
numbersQuery and manage numbers
pricingquery account prices
rcsSending RCS messages
smsSending SMS messages
statusQuery SMS status report
subaccountsEdit and view subaccounts
validate_for_voiceVerify phone numbers as sender
voiceSend voice messages
wabaSend WhatsApp Business messages

Multiple scopes can be specified using an url-encoded space. If the scope is not specified or is empty, the scopes you registered for the app are applied. You can only request scopes that are registered for your app - anything else is rejected with invalid_scope.


Reviewed and unreviewed apps

Self-created apps start out unreviewed. They are fully functional right away, but two limits apply:

  • Foreign accounts see a note on the authorization page saying the app has not been reviewed by seven.
  • The app can connect to at most 25 foreign accounts. Once that limit is reached, authorizing further accounts fails. Your own account and your subaccounts do not count towards it, so you can test without restriction.

On top of that, each account can own at most 10 unreviewed apps. Reviewed apps do not count towards that limit.

Once your app is meant to serve foreign accounts in production, request a review in the dashboard. A website must be set for this. We look at the name, logo, website and requested scopes, and after a successful review both the note and the connection limit are removed.


PHP code example

Here is a simple example in PHP. In the first code, the OAuth URL is generated and the customer is forwarded to it:

Redirect customer to OAuth2.0 page

<?php

// Application credentials
$client_id = 'testclient';
$client_secret = 'testsecret';

session_start();

// Request authorization for sms, analytics and lookup endpoints. // Leave empty to allow all scopes
$requested_scopes = [
  'sms',
  'analytics',
  'lookup'
];

// Generate random string for state
$state = bin2hex(openssl_random_pseudo_bytes(10));

// Store state in session
$_SESSION['state'] = $state;

// Build authorization URI
$auth_uri = 'https://oauth.seven.io/authorize?' .
  http_build_query([
    'response_type' => 'code',
    'client_id' => $client_id,
    'state' => $state,
    'scope' => implode(' ', $requested_scopes),
  ]);

// Redirect User to OAuth authorization site
header('Location: ' . $auth_uri);

The second code is the page that runs under your redirect_uri. Here the authorization is checked and the tokens are retrieved:

Checking authorization and retrieving tokens

<?php

// Application credentials $client_id = 'testclient'; 
$client_secret = 'testsecret'; 

session_start(); 

// CSRF check failed
if($_GET['state'] != $_SESSION['state']) {
  die('CSRF check failed');
}

// An error occured during authorization
elseif(isset($_GET['error'])) {
  die('Error: ' . $_GET['error']);
}

// We got a code, send it to OAuth 2.0 API to get the tokens...
elseif(isset($_GET['code'])) {
  $post_vars = http_build_query([
    'grant_type' => 'authorization_code',
    'code' => $_GET['code'],
  ]);

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_USERPWD, $client_id . ":" . $client_secret);

  curl_setopt($ch, CURLOPT_URL, 'https://oauth.seven.io/token');
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $post_vars);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);

  curl_close($ch);

  $token = json_decode($response);

  // You should store the tokens here in order to make API calls
  die("Access Token: " . $token->access_token);
}
Last updated: 1 day ago