<commit_before># API v4
The Splits.io API supports retrieving runs, runners, games, and categories, as well as uploading, disowning, and deleting
runs and managing races.

## Authentication & authorization

### Simple auth (run uploads only)
If the only thing you need to do on behalf of users is upload runs, you can do so anonymously then send the user to the
"claim URI" in the response's `uris.claim_uri` field. Sending a logged-in user here will cause the run to be claimed to
their account. Sending a logged-out user here will save the secret to browser local storage and prompt the user to sign
in to claim the run. They may do so immediately or at any later time.

The user must open the claim URI in their web browser for it to become theirs. If you need to upload runs without this
user intervention or want to do more with auth than uploading runs, use the OAuth option.

### OAuth (general purpose)
Splits.io supports the standard OAuth2 flow. You can request permission from the user to upload runs to their account or
perform other actions on their behalf. If they accept, you will receive an OAuth token which you can include in your API
requests in order to perform actions as that user.

The following instructions go into naive-case details about implementing this OAuth support in your application. If you
want to learn more about OAuth or need general OAuth troubleshooting help, you can
[research OAuth2 online][oauth2-simplified]. Especially if your application is a website, it's likely that the language
you're using has well-established libraries that handle much of the below OAuth flow for you. Look into those solutions
first to take the gruntwork out.

In all cases, you'll need to first go to your Splits.io account's [settings page][1] and create an application, then
refer to the relevant section below.

*Note: Once you have an OAuth token, you can use a request like this to retrieve information about it:*
```http
GET https://splits.io/oauth/token/info?access_token=YOUR_TOKEN
```

[oauth2-simplified]: https://aaronparecki.com/oauth-2-simplified/

#### Scopes
Below is a list of all the possible scopes your application can request along with a brief description. You can specify
multiple scopes by separating them with spaces in the auth token request.

| Scope         | Description                                         | Endpoints                                                                                                           |
|:--------------|:----------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------|
| `upload_run`  | Upload runs on behalf of the user                   | `POST https://splits.io/api/v4/runs`                                                                                |
| `delete_run`  | Delete or disown runs on behalf of the user         | `DELETE https://splits.io/api/v4/runs/:run_id` and `DELETE https://splits.io/api/v4/runs/:run_id/user` respectively |
| `manage_race` | Participate in races and chat on behalf of the user | See [Race][race]                                                                                                    |

<details>
<summary>Example 1: My application is an app that runs on the user's device</summary>

If your application runs locally as an app or program on the user's device, you should use OAuth's **authorization code grant
flow**. This means your application will open the Splits.io authorization page in the user's default browser, and if the
user accepts the authorization, Splits.io will give your application a `code` which you should immediately exchange for
an OAuth token using a secure API request.

1. Configure your program to run a small web server on a port of your choosing, and listen for `GET` requests to a path
    of your choosing. In this example, let's say you're listening on port 8000 for requests to `/auth/splitsio`.
2. On your Splits.io [settings page][1], set your `redirect_uri` to something like
    ```http
    http://localhost:8000/auth/splitsio
    ```
3. When a user wants to grant authorization to your application for their Splits.io account, send them to a URL like
    this:
    ```http
    https://splits.io/oauth/authorize?response_type=code&scope=upload_run&redirect_uri=http://localhost:8000/auth/splitsio&client_id=YOUR_CLIENT_ID
    ```
    If the user authorizes your application, they will be redirected to a URL like
    ```http
    http://localhost:8000/auth/splitsio?code=YOUR_CODE
    ```
    which the web server you set up in step 1 should respond to. Give the user a nice-looking HTML page saying to switch
    back to the application and strip the `code` URL parameter for the next step.
4. Use your `code` to make this request:
    ```http
    POST https://splits.io/oauth/token
    ```
    with this body:
    ```http
    grant_type=authorization_code
    client_id=YOUR_CLIENT_ID
    client_secret=YOUR_CLIENT_SECRET
    code=YOUR_CODE
    redirect_uri=http://localhost:8000/auth/splitsio
    ```
    which will respond with something like this:
    ```json
    {
      "access_token": "<PASSWORD>",
      "token_type": "bearer",
      "expires_in": 7200,
      "refresh_token": "<PASSWORD>",
      "scope": "upload_run",
      "created_at": 1499314941
    }
    ```
    Success! `access_token` is your OAuth token for the user. Use it in your API requests to act on behalf of the user
    by including this header in your requests:
    ```http
    Authorization: Bearer YOUR_ACCESS_TOKEN
    ```
    or by including an `access_token=YOUR_ACCESS_TOKEN` parameter.

    The access token expires after the duration specified in `expires_in` (measured in seconds). After it expires, you
    can retrieve a new one with no user intervention using the returned `refresh_token`:
    ```http
    POST https://splits.io/oauth/token
    ```
    ```http
    grant_type=refresh_token
    refresh_token=YOUR_REFRESH_TOKEN
    client_id=YOUR_CLIENT_ID
    client_secret=YOUR_CLIENT_SECRET
    ```
    This will return a new access token (and a new refresh token -- update yours!) in a body format identical to
    original grant (above).

    This style of expiring access tokens periodically and using refresh tokens to replace them improves security by
    making it obvious when a user's stolen credentials are in use. See [RFC 6749][rfc6749-6] for more information on
    refresh tokens.

</details>

<details>
<summary>Example 2: My application is an all-JavaScript website</summary>

If your application is an in-browser JavaScript application with little or no logic performed by a backend server, you
should use OAuth's **implicit grant flow**.

1. On your Splits.io [settings page][1], set your `redirect_uri` to where you want users to land after going through
   the authorization flow. For this example, we'll use
    ```http
    https://YOUR_WEBSITE/auth/splitsio
    ```
2. When a user wants to grant authorization to your application for their Splits.io account, send them to a URL like
    this:
    ```http
    https://splits.io/oauth/authorize?response_type=token&scope=upload_run&redirect_uri=https://YOUR_WEBSITE/auth/splitsio&client_id=YOUR_CLIENT_ID
    ```
    If the user authorizes your application, they will be redirected to a URL like
    ```http
    https://YOUR_WEBSITE/auth/splitsio#access_token=YOUR_TOKEN
    ```
    Success! `access_token` is your OAuth token for the user. Use it in your API requests to act on behalf of the user
    by including this header in your requests:
    ```http
    Authorization: Bearer YOUR_ACCESS_TOKEN
    ```
    The access token expires after the duration specified in `expires_in` (measured in seconds). After it expires, you
    can retrieve a new one with no user intervention using redirection upon accessing your app, or a hidden iframe to
    invisibly take the user through the authorization flow. If the user is still authorized, no user interaction will be
    required and you can strip your new access token from the URL fragment.

    This style of expiring access tokens periodically improves security by limiting the usability of any stolen
    credentials.
</details>

<details>
<summary>Example 3: My application is a website</summary>

If your application is a website with a backend component, you should use OAuth's **authorization code grant flow**.
This means your website will link the user to the Splits.io authorization page, and if the user accepts the
authorization, Splits.io will give your application a `code` which it will immediately exchange for an OAuth token using
a secure API request.

1. On your Splits.io [settings page][1], set your `redirect_uri` to where you want users to land after going through
   the authorization flow. For this example, we'll use
    ```http
    https://YOUR_WEBSITE/auth/splitsio
    ```
2. When a user wants to grant authorization to your application for their Splits.io account, send them to a URL like
    this:
    ```http
    https://splits.io/oauth/authorize?response_type=code&scope=upload_run&redirect_uri=https://YOUR_WEBSITE/auth/splitsio&client_id=YOUR_CLIENT_ID
    ```
    If the user authorizes your application, they will be redirected to a URL like
    ```http
    https://YOUR_WEBSITE/auth/splitsio?code=YOUR_CODE
    ```
    Strip the `code` URL parameter for the next step.
4. Use your `code` to make this request:
    ```http
    POST https://splits.io/oauth/token
    ```
    with this body:
    ```http
    grant_type=authorization_code
    client_id=YOUR_CLIENT_ID
    client_secret=YOUR_CLIENT_SECRET
    code=YOUR_CODE
    redirect_uri=http://localhost:8000/auth/splitsio
    ```
    which will respond with something like this:
    ```json
    {
      "access_token": "0e82e0ac69fed3c6e5044682a9eb94ccded5ace70e84838104a131cb50595cd2",
      "token_type": "bearer",
      "expires_in": 7200,
      "refresh_token": "<PASSWORD>",
      "scope": "upload_run",
      "created_at": 1499314941<commit_msg>Clarify some sentences about using `code`<commit_after># API v4
The Splits.io API supports retrieving runs, runners, games, and categories, as well as uploading, disowning, and deleting
runs and managing races.

## Authentication & authorization

### Simple auth (run uploads only)
If the only thing you need to do on behalf of users is upload runs, you can do so anonymously then send the user to the
"claim URI" in the response's `uris.claim_uri` field. Sending a logged-in user here will cause the run to be claimed to
their account. Sending a logged-out user here will save the secret to browser local storage and prompt the user to sign
in to claim the run. They may do so immediately or at any later time.

The user must open the claim URI in their web browser for it to become theirs. If you need to upload runs without this
user intervention or want to do more with auth than uploading runs, use the OAuth option.

### OAuth (general purpose)
Splits.io supports the standard OAuth2 flow. You can request permission from the user to upload runs to their account or
perform other actions on their behalf. If they accept, you will receive an OAuth token which you can include in your API
requests in order to perform actions as that user.

The following instructions go into naive-case details about implementing this OAuth support in your application. If you
want to learn more about OAuth or need general OAuth troubleshooting help, you can
[research OAuth2 online][oauth2-simplified]. Especially if your application is a website, it's likely that the language
you're using has well-established libraries that handle much of the below OAuth flow for you. Look into those solutions
first to take the gruntwork out.

In all cases, you'll need to first go to your Splits.io account's [settings page][1] and create an application, then
refer to the relevant section below.

*Note: Once you have an OAuth token, you can use a request like this to retrieve information about it:*
```http
GET https://splits.io/oauth/token/info?access_token=YOUR_TOKEN
```

[oauth2-simplified]: https://aaronparecki.com/oauth-2-simplified/

#### Scopes
Below is a list of all the possible scopes your application can request along with a brief description. You can specify
multiple scopes by separating them with spaces in the auth token request.

| Scope         | Description                                         | Endpoints                                                                                                           |
|:--------------|:----------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------|
| `upload_run`  | Upload runs on behalf of the user                   | `POST https://splits.io/api/v4/runs`                                                                                |
| `delete_run`  | Delete or disown runs on behalf of the user         | `DELETE https://splits.io/api/v4/runs/:run_id` and `DELETE https://splits.io/api/v4/runs/:run_id/user` respectively |
| `manage_race` | Participate in races and chat on behalf of the user | See [Race][race]                                                                                                    |

<details>
<summary>Example 1: My application is an app that runs on the user's device</summary>

If your application runs locally as an app or program on the user's device, you should use OAuth's **authorization code grant
flow**. This means your application will open the Splits.io authorization page in the user's default browser, and if the
user accepts the authorization, Splits.io will give your application a `code` which you should immediately exchange for
an OAuth token using a secure API request.

1. Configure your program to run a small web server on a port of your choosing, and listen for `GET` requests to a path
    of your choosing. In this example, let's say you're listening on port 8000 for requests to `/auth/splitsio`.
2. On your Splits.io [settings page][1], set your `redirect_uri` to something like
    ```http
    http://localhost:8000/auth/splitsio
    ```
3. When a user wants to grant authorization to your application for their Splits.io account, send them to a URL like
    this:
    ```http
    https://splits.io/oauth/authorize?response_type=code&scope=upload_run&redirect_uri=http://localhost:8000/auth/splitsio&client_id=YOUR_CLIENT_ID
    ```
    If the user authorizes your application, they will be redirected to a URL like
    ```http
    http://localhost:8000/auth/splitsio?code=YOUR_CODE
    ```
    which the web server you set up in step 1 should respond to. Give the user a nice-looking HTML page saying to switch
    back to the application. Have your application strip the `code` URL parameter for the next step.
4. Use your `code` to make this request:
    ```http
    POST https://splits.io/oauth/token
    ```
    with this body:
    ```http
    grant_type=authorization_code
    client_id=YOUR_CLIENT_ID
    client_secret=YOUR_CLIENT_SECRET
    code=YOUR_CODE
    redirect_uri=http://localhost:8000/auth/splitsio
    ```
    which will respond with something like this:
    ```json
    {
      "access_token": "0e82e0ac69fed3c6e5044682a9eb94ccded5ace70e84838104a131cb50595cd2",
      "token_type": "bearer",
      "expires_in": 7200,
      "refresh_token": "<PASSWORD>",
      "scope": "upload_run",
      "created_at": 1499314941
    }
    ```
    Success! `access_token` is your OAuth token for the user. Use it in your API requests to act on behalf of the user
    by including this header in your requests:
    ```http
    Authorization: Bearer YOUR_ACCESS_TOKEN
    ```
    or by including an `access_token=YOUR_ACCESS_TOKEN` parameter.

    The access token expires after the duration specified in `expires_in` (measured in seconds). After it expires, you
    can retrieve a new one with no user intervention using the returned `refresh_token`:
    ```http
    POST https://splits.io/oauth/token
    ```
    ```http
    grant_type=refresh_token
    refresh_token=YOUR_REFRESH_TOKEN
    client_id=YOUR_CLIENT_ID
    client_secret=YOUR_CLIENT_SECRET
    ```
    This will return a new access token (and a new refresh token -- update yours!) in a body format identical to
    original grant (above).

    This style of expiring access tokens periodically and using refresh tokens to replace them improves security by
    making it obvious when a user's stolen credentials are in use. See [RFC 6749][rfc6749-6] for more information on
    refresh tokens.

</details>

<details>
<summary>Example 2: My application is an all-JavaScript website</summary>

If your application is an in-browser JavaScript application with little or no logic performed by a backend server, you
should use OAuth's **implicit grant flow**.

1. On your Splits.io [settings page][1], set your `redirect_uri` to where you want users to land after going through
   the authorization flow. For this example, we'll use
    ```http
    https://YOUR_WEBSITE/auth/splitsio
    ```
2. When a user wants to grant authorization to your application for their Splits.io account, send them to a URL like
    this:
    ```http
    https://splits.io/oauth/authorize?response_type=token&scope=upload_run&redirect_uri=https://YOUR_WEBSITE/auth/splitsio&client_id=YOUR_CLIENT_ID
    ```
    If the user authorizes your application, they will be redirected to a URL like
    ```http
    https://YOUR_WEBSITE/auth/splitsio#access_token=YOUR_TOKEN
    ```
    Success! `access_token` is your OAuth token for the user. Use it in your API requests to act on behalf of the user
    by including this header in your requests:
    ```http
    Authorization: Bearer YOUR_ACCESS_TOKEN
    ```
    The access token expires after the duration specified in `expires_in` (measured in seconds). After it expires, you
    can retrieve a new one with no user intervention using redirection upon accessing your app, or a hidden iframe to
    invisibly take the user through the authorization flow. If the user is still authorized, no user interaction will be
    required and you can strip your new access token from the URL fragment.

    This style of expiring access tokens periodically improves security by limiting the usability of any stolen
    credentials.
</details>

<details>
<summary>Example 3: My application is a website</summary>

If your application is a website with a backend component, you should use OAuth's **authorization code grant flow**.
This means your website will link the user to the Splits.io authorization page, and if the user accepts the
authorization, Splits.io will give your application a `code` which it will immediately exchange for an OAuth token using
a secure API request.

1. On your Splits.io [settings page][1], set your `redirect_uri` to where you want users to land after going through
   the authorization flow. For this example, we'll use
    ```http
    https://YOUR_WEBSITE/auth/splitsio
    ```
2. When a user wants to grant authorization to your application for their Splits.io account, send them to a URL like
    this:
    ```http
    https://splits.io/oauth/authorize?response_type=code&scope=upload_run&redirect_uri=https://YOUR_WEBSITE/auth/splitsio&client_id=YOUR_CLIENT_ID
    ```
    If the user authorizes your application, they will be redirected to a URL like
    ```http
    https://YOUR_WEBSITE/auth/splitsio?code=YOUR_CODE
    ```
    Have your application strip the `code` URL parameter for the next step.
4. Use your `code` to make this request:
    ```http
    POST https://splits.io/oauth/token
    ```
    with this body:
    ```http
    grant_type=authorization_code
    client_id=YOUR_CLIENT_ID
    client_secret=YOUR_CLIENT_SECRET
    code=YOUR_CODE
    redirect_uri=http://localhost:8000/auth/splitsio
    ```
    which will respond with something like this:
    ```json
    {
      "access_token": "0<PASSWORD>",
      "token_type": "bearer",
      "expires_in": 7200,
      "refresh_token": "<PASSWORD>",
      "scope": "upload_run",
      "created_at": 1499314941
{'fraction_non_alphanumeric': 0.08756697757491566, 'fraction_numerical': 0.012452867632466759, 'mean_word_length': 3.059001208215868, 'pattern_counts': {'":': 24, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 34, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1586903', 'n_tokens_mistral': 5625, 'n_tokens_neox': 5312, 'n_words': 2409}