# How To Create API Tasks

**With API Tasks, the Truebit Verify Hub proxies requests to an external API endpoint**. API Tasks are dispatched and executed only by the Truebit Verify Hub, which secures sensitive data such as API credentials and allows for execution of a single, audited API call. In a role reversal, Truebit Verify Nodes then audit the network transaction originated by the hub, providing full transparency for each call. &#x20;

API Tasks are accessed via a built-in web services interface provided by the Truebit Verify Hub, and can be called by any application using HTTP. **Each API Task execution is recorded in a transcript.**

#### Trusted Execution for API Tasks

All API Task executions are performed within a [Trusted Execution Environment (TEE)](/overview/how-does-truebit-work.md), ensuring that sensitive data and credentials remain private throughout the entire execution process. This adds an additional layer of trust and confidentiality to every API interaction.

By leveraging TEE-backed execution, Truebit provides:

* **Credential privacy:** Authentication keys remain encrypted and protected within a secure enclave, never exposed to external systems or verifiers.
* **Tamper-proof execution**: The API call and its outputs cannot be modified or inspected during runtime, preserving the integrity of the operation.
* **Verified transparency**: Even with private execution, each API Task still produces a verifiable transcript that confirms the request occurred exactly as intended.
* **End-to-end trust**: The combination of TEE execution and Truebit’s verification model ensures API Tasks are both private and provably correct — offering a secure, auditable bridge between systems that handle sensitive or regulated data.

This approach extends the security of hardware-backed trusted execution to the API layer, enabling developers to confidently automate API calls without compromising privacy or integrity.

## Prerequisites

There are several important considerations when defining an API Task:

* **OpenAPI Schemas:** Truebit Verify uses the [OpenAPI schema specification](https://spec.openapis.org/oas/v3.1.0#openapi-specification) as the basis for the API Manifest that defines the interaction with an external HTTP-based API. The OpenAPI schema describes the servers, data formats, validation rules, etc. for a given API endpoint. The Truebit Verify Hub will validate all API Task calls using the OpenAPI schema before executing a network request. Many APIs already provide an OpenAPI schema as part of their documentation — and this can serve as a good starting point for defining your API Manifest. Truebit supports OpenAPI Schema v3 and later.
* **Credentials:** Many APIs require authentication credentials to be provided as part of the network request. We currently support `basic auth, AWS key, and custom HTTP Header` credentials. The Truebit Verify CLI allows you to upload encrypted credentials to the Truebit Verify Hub, where they will be securely stored in their encrypted state. When possible, we recommend obtaining credentials specifically scoped to the authorization requirements of your API Task, and rotating credentials in accordance with your team's security practices.
* **No Determinsim Requirement**: Truebit Verify uses a different verification strategy for APIs which does not require deterministic outputs to be provided by the API.&#x20;

### Building An API Task

To interact with the Truebit protocol, developers can define **API Tasks** that encapsulate computation logic and interface with external systems. This section outlines the steps required to build, configure, and deploy an API Task within the Truebit ecosystem.

### 1. Define The API Manifest

The [task developer](/overview/what-is-truebit-verify.md#task-developers) provides an OpenAPI schema as an API Manifest for the relevant APIs that will be proxied by Truebit Verify. We recommend using a tool like [Swagger Editor](https://editor.swagger.io/) to help develop the OpenAPI schema used in your manifest. If using a pre-existing OpenAPI schema provided by an API publisher, we recommend reviewing the contents of the schema to remove any unneeded endpoints and/or add any additional validation rules as needed by your API Task.

#### Using OpenAPI For The Manifest

OpenAPI Specification (formerly Swagger Specification) is an API description format for REST APIs. An OpenAPI file allows you to describe an entire API, including:

* Available endpoints (/users) and operations on each endpoint (GET /users, POST /users).
* Operation parameters Input and output for each operation.
* Authentication methods.
* Contact information, license, terms of use and other information.

#### Advantages

* **Standardized Integration:** Leverages widely used industry standards to ensure compatibility across diverse environments.
* **OpenAPI Compatibility**: Most APIs come with ready-to-use OpenAPI specifications, streamlining the integration process within the Truebit ecosystem.
* **Native Validation Support:** Built-in mechanisms ensure that data integrity and task requirements are automatically verified.
* **Granular Customization**: Offers the flexibility to include or exclude specific fields, optimizing data transfer and processing efficiency.
* **Secure Extensibility:** Supports the inclusion of credentials and custom definitions through robust extensibility mechanisms.

#### Example

<details>

<summary>PET SHOP example manifest</summary>

{% code overflow="wrap" lineNumbers="true" fullWidth="false" %}

```json
{
  "openapi": "3.0.3",
  "info": {
    "title": "Swagger Petstore - OpenAPI 3.0",
    "description": "This is a sample Pet Store Server based on the OpenAPI 3.0 specification.",
    "contact": {
      "email": "apiteam@swagger.io"
    },
    "license": {
      "name": "Apache 2.0",
      "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
    },
    "version": "1.0.11"
  },
  "externalDocs": {
    "description": "Find out more about Swagger",
    "url": "http://swagger.io"
  },
  "servers": [
    {
      "url": "https://petstore3.swagger.io/api/v3"
    }
  ],
  "paths": {
    "/store/order": {
      "post": {
        "tags": [
          "store"
        ],
        "summary": "Place an order for a pet",
        "description": "Place a new order in the store",
        "operationId": "placeOrder",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Order"
              }
            },
            "application/xml": {
              "schema": {
                "$ref": "#/components/schemas/Order"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/Order"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              }
            }
          },
          "405": {
            "description": "Invalid input"
          }
        }
      }
    },
    "/store/order/{orderId}": {
      "get": {
        "tags": [
          "store"
        ],
        "summary": "Find purchase order by ID",
        "description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions.",
        "operationId": "getOrderById",
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "description": "ID of order that needs to be fetched",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              },
              "application/xml": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              }
            }
          },
          "400": {
            "description": "Invalid ID supplied"
          },
          "404": {
            "description": "Order not found"
          }
        }
      },
      "delete": {
        "tags": [
          "store"
        ],
        "summary": "Delete purchase order by ID",
        "description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors",
        "operationId": "deleteOrder",
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "description": "ID of the order that needs to be deleted",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Invalid ID supplied"
          },
          "404": {
            "description": "Order not found"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Order": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "example": 10
          },
          "petId": {
            "type": "integer",
            "format": "int64",
            "example": 198772
          },
          "quantity": {
            "type": "integer",
            "format": "int32",
            "example": 7
          },
          "shipDate": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string",
            "description": "Order Status",
            "example": "approved",
            "enum": [
              "placed",
              "approved",
              "delivered"
            ]
          },
          "complete": {
            "type": "boolean"
          }
        },
        "xml": {
          "name": "order"
        }
      },
      "ApiResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "integer",
            "format": "int32"
          },
          "type": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "xml": {
          "name": "##default"
        }
      }
    }
  }
}
```

{% endcode %}

</details>

### 2. Develop The API Task

The [Task Developer](/overview/how-do-you-intend-to-use-truebit.md) creates a new API task by calling the [create-api](/developing-truebit-tasks/truebit-cli-reference.md#create-api) command from the [Truebit CLI](/developing-truebit-tasks/truebit-cli-reference.md) using the defined manifest as the input parameter.  As a result, a new [`taskId`](/community/glossary.md) will be returned.

### 3. Test The API Task

The [Task Developer](/overview/how-do-you-intend-to-use-truebit.md) tests the API task using the [start-api](/developing-truebit-tasks/truebit-cli-reference.md#start-api) command from the [Truebit CLI](/developing-truebit-tasks/truebit-cli-reference.md).

### What If Authentication is Required?

{% hint style="warning" %}
An API Task must use a single authentication method across all endpoints and cannot include both public and private endpoints in the same manifest.
{% endhint %}

**If the API endpoint you want to call is authenticated, you'll need to provide the necessary credentials when running the start-api command.**

\
Currently, we support three authentication methods:

* `custom-header`
* `basic-auth`
* `aws-signature`

#### How To Pass Credentials

#### **Custom Header**

Use this method when the API expects authentication via custom headers.

{% code overflow="wrap" %}

```bash
truebit start-api [options] <manifestPath> <input> custom-header "username:<username>,password:<password>"
```

{% endcode %}

#### **Basic Auth**

For standard HTTP Basic Authentication, you will need to use the following:

{% code overflow="wrap" %}

```bash
truebit start-api [options] <manifestPath> <input> basic-auth "username:<username>,password:<password>"
```

{% endcode %}

#### **AWS Signature**

For endpoints protected with AWS Signature Version 4, you will need to use the following:

{% code overflow="wrap" %}

```bash
truebit start-api [options] <manifestPath> <input> aws-signature "accessKey:<accesskey>,secretKey:<secretkey>"
```

{% endcode %}

### 4. Deploy The API Task

When the API Task is ready, the [Task Developer](/overview/what-is-truebit-verify.md#task-developers) deploys the task using the [deploy](/developing-truebit-tasks/truebit-cli-reference.md#deploy) command from the [Truebit CLI](/developing-truebit-tasks/truebit-cli-reference.md).

### Deploying Credentials For Authenticated Endpoints

If the endpoints defined in your manifest require authentication (custom-header, basic-auth, or aws-signature), you must also deploy the corresponding credentials to ensure the [Task Requester](/overview/how-do-you-intend-to-use-truebit.md#task-requesters) can execute the task successfully.

To do this, use the [api-auth](/developing-truebit-tasks/truebit-cli-reference.md#api-auth) command along with the appropriate authentication method and credentials:

{% code overflow="wrap" %}

```bash
truebit api-auth <namespace> <taskname> <taskId> <authType> <authString>
```

{% endcode %}

#### Authorize The Task execution

The Task Authorization process is an optional step, but it becomes mandatory when the Task Requester has registered the task. This step allows the Task Developer to define who has permission to execute the deployed task.

{% hint style="info" %}
Click Here to see more information about the [**Task Authorization**](/developing-truebit-tasks/task-authorization.md) process.&#x20;
{% endhint %}

### 5. Execute The API Task

The [Task Requester](/overview/what-is-truebit-verify.md#task-requesters) executes the task using the [Task Execution Endpoint](/integrating-truebit-tasks/api-task-execution.md) from the Truebit API.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://devs.truebit.io/developing-truebit-tasks/how-to-create-api-tasks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
