> ## Documentation Index
> Fetch the complete documentation index at: https://www.propeldata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Authenticate your API requests.

<div />

<CardGroup cols={2}>
  <Card title="Server-side authentication" icon="server" href="#server-side-authentication">
    Use long-lived API Keys to authenticate server-side backend applications.
  </Card>

  <Card title="Client-side authentication" icon="browser" href="#client-side-authentication">
    Use short-lived JWT tokens to authenticate client-side frontend applications.
  </Card>
</CardGroup>

## Get your API credentials

To get your API credentials, [create an Application](https://console.propeldata.com/application/new/) in the Propel Console with `DATA_POOL_QUERY` and `METRIC_QUERY` scopes so they can access your data.

<Info>
  If you are using the [Management API](/docs/management-api), you need an Application with `ADMIN` scope.
</Info>

For step-by-step instructions, see the [Creating an Application guide](/docs/applications#creating-an-application).

## Server-side authentication

Authenticate server-side applications using an Application ID and secret as HTTP Basic Authentication credentials.

Use the Application ID as username and secret as password in the HTTP Basic Authorization header:

<CodeGroup>
  ```bash curl {2} theme={"system"}
  curl -X POST https://api.us-east-2.propeldata.com/graphql \
  -u $APPLICATION_ID:$APPLICATION_SECRET \
  -H "Content-Type: application/json" \
  -d '{"query": "query SqlV1 { sqlV1(input: { query: \"SELECT 1;\" }) { columns { columnName } rows } }"}'
  ```
</CodeGroup>

## Client-side authentication

Authenticate client-side frontend applications using short-lived JWT tokens. This involves a two-step process:

<Steps>
  <Step title="Generate a JWT token">
    Make a POST request to the Token API endpoint with your Application credentials from secure backend code.

    <CodeGroup>
      ```bash curl theme={"system"}
      curl -X POST https://auth.us-east-2.propeldata.com/oauth2/token \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=client_credentials&client_id=$APPLICATION_ID&client_secret=$APPLICATION_SECRET"
      ```

      ```jsx Javascript theme={"system"}
      import fetch from 'node-fetch'

      const response = await fetch(
        'https://auth.us-east-2.propeldata.com/oauth2/token',
        {
          method: 'post',
          body: 'grant_type=client_credentials&client_id=$APPLICATION_ID&client_secret=$APPLICATION_SECRET',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
        }
      )
      const data = await response.json()

      console.log(data.access_token)
      ```
    </CodeGroup>

    Replace `$APPLICATION_ID` and `$APPLICATION_SECRET` with your Application's `clientId` and `secret`.

    The response includes:

    ```json theme={"system"}
    {
      "access_token": "eyJra...",
      "expires_in": 3600,
      "token_type": "Bearer"
    }
    ```
  </Step>

  <Step title="Make an authenticated request">
    Once you've received an access token, your application makes API requests by including the Authorization header with your access token.

    <CodeGroup>
      ```bash curl theme={"system"}
      curl -X POST https://api.us-east-2.propeldata.com/graphql \
      -H "Authorization: Bearer eyJra..." \
      -H "Content-Type: application/json" \
      -d '{"query": "query SqlV1 { sqlV1(input: { query: \"SELECT 1;\" }) { columns { columnName } rows } }"}'
      ```

      ```jsx theme={"system"}
      import fetch from 'node-fetch'

      const response = await fetch('https://api.us-east-2.propeldata.com/graphql', {
        method: 'post',
        headers: { Authorization: 'Bearer eyJra...' },
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify('{getAllDataSources (first:10) { pageInfo edges }}')
      })
      const data = await response.json()

      console.log(data.access_token)
      ```
    </CodeGroup>
  </Step>
</Steps>

### Error handling

<AccordionGroup>
  <Accordion title="400 Bad request" icon="circle-xmark">
    The Token API will return a 400 Bad Request response if:

    * The `grant_type` parameter is missing or invalid
    * The `client_id` parameter is missing or invalid
    * The `client_secret` parameter is missing or invalid

    To resolve this:

    1. Verify you've created a Propel Application in your Account
    2. Confirm your Application secret is correct
    3. Ensure you include `grant_type=client_credentials` in the request
  </Accordion>

  <Accordion title="401 Unauthorized" icon="lock">
    The API will return a 401 Unauthorized response when using an invalid access token. Common causes include:

    * The token has expired
    * The token was revoked
    * The token is malformed

    Your application should handle 401 errors by requesting a new access token.
  </Accordion>

  <Accordion title="403 Forbidden" icon="ban">
    The API will return a 403 Forbidden response when the access token lacks the required permissions to access a resource. This means:

    * The token does not have the necessary scopes
    * The token does not have the required policies

    Check your Application's permissions in the Propel Console.
  </Accordion>
</AccordionGroup>
