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

# API overview

> Our API powers everything in the app— our UI makes calls to the backend, which operates the app. You can learn more about how these work and make your own calls in this section.

Want to jump-in and interact with Mage via API? Follow the [quickstart](#quickstart) below to get going! Otherwise, head to the [components](#components) section to learn about how our API is structured— this will be helpful if you're interested in adding new API endpoints or developing Mage.

You can read more about the components in the *Design* section on the sidebar to the left— it contains pages for [Resources](api-reference/resources), [Policies](api-reference/policies), and [Presenters](api-reference/presenters), which are the three components that make up an API endpoint.

## Quickstart

<AccordionGroup>
  <Accordion title="Obtain API Key" icon="key">
    You'll need your API key to authenticate calls. You can find your API key quickly by navigating to the GUI and checking the network request log from the container.

    You can read more about how to do this on Chromium based browsers [here](https://developers.google.com/web/tools/chrome-devtools/network/reference#headers).

    Once you have your API key, we recommend storing it as a secret and using a solution like [dotenv](https://pypi.org/project/python-dotenv/) to load it into your environment. This will prevent you from exposing it as plain text.
  </Accordion>

  <Accordion title="Initialize Session" icon="car">
    <Snippet file="initialize-session.mdx" />
  </Accordion>

  <Accordion title="Authenticate Session" icon="lock">
    To authenticate your session, we recommend using the `oauth_token` cookie. This can be done simply in Python requests with the following, where `token` is the value of the `token` key in the response payload:

    ```python theme={"system"}
    token = mage_session.get('token')
    s.headers['Cookie'] = f'oauth_token={token}'
    ```
  </Accordion>

  <Accordion title="Make API calls" icon="phone">
    With your API session configured, you can now make API calls! Here's an example of how to list all pipelines:

    ```python theme={"system"}
    pipelines_url = base_url + '/api/pipelines'
    r = s.get(pipelines_url)
    list_pipelines = r.json()

    print(list_pipelines)
    ```
  </Accordion>
</AccordionGroup>

## Authentication

Most API endpoints require authentication. The API request must include the following:

1. API key
2. OAuth token

### API key

The API request must include the API key in the query parameter as `api_key` or in the request payload body as `api_key`. You can find your API key quickly by navigating to the GUI and checking the request log from the container or going to the "Network" tab in your browser's developer tools.

### OAuth token

The OAuth token is generated by creating a new [session](/api-reference/sessions). Sessions are only required when `REQUIRE_USER_AUTHENTICATION` is enabled for your project— that is, when users must login to access Mage.

The token provided in the session payload is the **raw** value. There are two ways to authenticate with this token:

1. Supply the raw token in the header as:

```json theme={"system"}
{"Cookie": "oauth_token=[RAW-TOKEN-FROM-RESPONSE]"}
```

2. Supply the decoded token in the header as:

```json theme={"system"}
{"OAUTH-TOKEN": "[DECODED-TOKEN-FROM-RESPONSE]"}
```

To decode a token:

<CodeGroup>
  ```python Python theme={"system"}
  from mage_ai.authentication.oauth2 import decode_token

  decoded_token = decode_token(token_from_session_response) ['token']
  ```
</CodeGroup>

### Examples

Decoded token, API key in in URL:

```curl theme={"system"}
curl -X GET "localhost:6789/api/pipelines?api_key=zkWlN0PkIKSN0C11CfUHUj84OT5XOJ6tDZ6bDRO2" \
    -H "OAUTH-TOKEN: [DECODED-TOKEN-FROM-RESPONSE]"
```

Decoded token, API key in body:

```curl theme={"system"}
curl -X POST "localhost:6789/api/pipelines" \
    -H "OAUTH-TOKEN: [DECODED-TOKEN-FROM-RESPONSE]" \
    -d '{
        "api_key": "zkWlN0PkIKSN0C11CfUHUj84OT5XOJ6tDZ6bDRO2",
        "pipeline": {}
    }'
```

Raw token, API key in body:

```curl theme={"system"}
curl -X POST "localhost:6789/api/pipelines" \
    -H "Cookie: oauth_token=[RAW-TOKEN-FROM-RESPONSE]" \
    -d '{
        "api_key": "zkWlN0PkIKSN0C11CfUHUj84OT5XOJ6tDZ6bDRO2",
        "pipeline": {}
    }'
```

### Responses

*All* our responses return a `200` status in the main payload. The any error code will be stored in the `error` key. For example, the following is a response from a failed session auth:

```json theme={"system"}
{
    "error": {
        "code": 404,
        "message": "Email/username and/or password invalid.",
        "type": "record_not_found"
    },
    "status": 200
}
```

To check for an error, one might try a solution like the following:

<CodeGroup>
  ```python Python theme={"system"}
  err_code = r.json().get('error').get('code'):
  ```
</CodeGroup>

## Components

If you're not developing our API, you can jump right in and start querying endpoints using the [quickstart](#quickstart) above. Otherwise, our API is based on three components:

1. [Resources](/api-reference/resources)
2. [Policies](/api-reference/policies)
3. [Presenters](/api-reference/presenters)

If you'd like to contribute a new endpoint, you'll need to create one of each. To update an endpoint, it's important to understand how they work together.

**Resources** are the core of the API. They define the endpoints and the logic behind them. They are the only component that is required to create a new endpoint. They are also the only component that is required to update an existing endpoint.

**Policies** determine what actions can be taken on a resource: what attributes can be read, and which attributes can be written.

**Presenters** determine what attributes of the resource are returned to the client in the response. You can have different sets of attributes be included in the response based on the action (e.g. create, detail, delete, list, update) or a custom format.

To see examples of each, take a look at the `mage-ai/mage_ai/api` directory [here](https://github.com/mage-ai/mage-ai/tree/master/mage_ai/api).

## Testing

Create a test file in `mage_ai/tests/api/operations/test_[resource_name].py`;
replace `resource_name` with the name of your resource.

Paste in the following sample code into your file:

```python theme={"system"}
from mage_ai.orchestration.db.models.oauth import User
from mage_ai.tests.api.operations.base import BaseApiTestCase
from mage_ai.tests.factory import create_user


class SomeResourceOperationTests(BaseApiTestCase):
    model_class = User

    async def test_execute_delete(self):
        user = create_user(email=self.faker.email())

        await self.base_test_execute_delete(user.id)

    async def test_execute_detail(self):
        user = create_user()
        await self.base_test_execute_detail(user.id, dict(
            email=user.email,
            username=user.username,
        ))
```

This is only a sample test file. It’s running tests on the `UserResource`.
You’ll need to update the test logic to unit test your custom API endpoint.
