Want to jump-in and interact with Mage via API? Follow the quickstart below to get going! Otherwise, head to the 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, Policies, and Presenters, which are the three components that make up an API endpoint.

Quickstart

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. 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:
{"Cookie": "oauth_token=[RAW-TOKEN-FROM-RESPONSE]"}
  1. Supply the decoded token in the header as:
{"OAUTH-TOKEN": "[DECODED-TOKEN-FROM-RESPONSE]"}

To decode a token:

Examples

Decoded token, API key in in URL:

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

Decoded token, API key in body:

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 -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:

{
    "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:

Components

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

  1. Resources
  2. Policies
  3. 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.

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:

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.