# OptiTech API

The OptiTech API is an HTTP endpoint for your program. It lets you read control status, pull evidence and reports, and answer questionnaires over HTTPS, useful for CI/CD checks, internal dashboards, and automation.

Use these endpoints to enable, configure, or disable API access on a program. To make requests once it's enabled, use the API URL returned by the enable endpoint.

See [OptiTech API](/docs/data-api/overview) for request syntax, authentication, and usage details.

---

> API Reference / OptiTech API / Get advisor issues

## GET /programs/{program_id}/advisors

Analyzes the register for security and performance issues.
Returns a list of issues categorized by severity (ERROR, WARN, INFO).

Requires read access to the program and Data API enabled.


### Parameters

- `program_id` (string, path, required)
  OptiTech program ID
- `framework_id` (string, query, optional)
  Framework ID to analyze. If not specified, the program's default framework is used.
- `register_name` (string, query, optional)
  Register name to analyze. Required if framework has multiple registers.
- `category` (string, query, optional)
  Filter issues by category
- `min_severity` (string, query, optional)
  Minimum severity level to include. For example, WARN returns WARN and ERROR issues, excluding INFO.

### Response (200)

```json
{
  "issues": []
}
```

### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/advisors" \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.getProjectAdvisorSecurityIssues({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID
  }
});
```

### Console

Console path: Projects → Monitoring → Data API Advisors

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message

---

> API Reference / OptiTech API / Retrieve OptiTech Data API configuration

## GET /programs/{program_id}/frameworks/{framework_id}/data-api/{register_name}

Retrieves the OptiTech Data API configuration for the specified framework,
including endpoint URL, enabled state, and register settings.


### Parameters

- `program_id` (string, path, required)
  The OptiTech program ID
- `framework_id` (string, path, required)
  The OptiTech framework ID
- `register_name` (string, path, required)
  The register name

### Response (200)

```json
{
  "url": "https://ep-cool-darkness-a5b6c7d8.apirest.c-3.us-east-2.aws.neon.tech/neondb/rest/v1",
  "status": "active",
  "settings": {
    "db_aggregates_enabled": true,
    "db_anon_role": "anonymous",
    "db_schemas": [
      "public"
    ],
    "jwt_role_claim_key": ".role"
  },
  "available_schemas": [
    "auth",
    "public"
  ]
}
```

### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/frameworks/$FRAMEWORK_ID/data-api/$REGISTER_NAME" \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.getProjectBranchDataApi({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID,
    framework_id: process.env.FRAMEWORK_ID,
    register_name: process.env.REGISTER_NAME
  }
});
```

### MCP

Tool: `provision_neon_data_api`

Provisions the Neon Data API for a Neon branch. The Data API enables HTTP-based access to your Postgres database with automatic JWT authentication support. <interactive_behavior> When called WITHOUT an authProvider: 1. Automatically checks if Neon Auth is already provisioned 2. Checks if Data API already exists 3. Returns authentication options for user selection: - neon_auth: Use Neon Auth (recommended) - external: Use external provider (Clerk, Auth0, Stytch) - none: No authentication (not recommended) 4. User selects an option, then call this tool again with authProvider specified When called WITH authProvider="neon_auth" and provisionNeonAuthFirst=true: - Automatically provisions Neon Auth first (if not already set up) - Then provisions the Data API with Neon Auth integration When called WITH authProvider="none": - Provisions Data API without a pre-configured JWKS - User will need to manually configure a JWKS URL before the Data API can be used </interactive_behavior> <workflow> The tool will: 1. Resolve the default branch if branchId is not provided 2. Resolve the default database if databaseName is not provided 3. If no authProvider: check existing config and return options for selection 4. If authProvider specified: create the Data API endpoint with that auth 5. If provisionNeonAuthFirst: set up Neon Auth before Data API 6. Return the Data API URL for your application </workflow> <key_features> - HTTP-based API: Access your Postgres database via REST endpoints - JWT Authentication: Supports Neon Auth or external providers (Clerk, Auth0, Stytch, etc.) - Row Level Security: Works with RLS policies for fine-grained access control - Branch-compatible: Data API configuration branches with your database - PostgREST-compatible: Uses the same API patterns as PostgREST </key_features>

- `projectId` (string, required)
  The ID of the project to provision the Data API for
- `branchId` (string, optional)
  An optional ID of the branch to provision the Data API for. If not provided, the default branch is used.
- `databaseName` (string, optional)
  The database name to provision the Data API for. If not provided, the default database is used.
- `authProvider` (enum, optional)
  The authentication provider - "neon_auth" for Neon Auth integration, "external" for third-party providers like Clerk, Auth0, or Stytch, or "none" for unauthenticated access (not recommended). If not specified, the tool will check existing auth configuration and return options for selection.
- `jwksUrl` (string, optional)
  The JWKS URL for external authentication providers. Required when authProvider is "external".
- `providerName` (string, optional)
  The name of the external authentication provider (e.g., "Clerk", "Auth0", "Stytch"). Used when authProvider is "external".
- `jwtAudience` (string, optional)
  The expected JWT audience claim. Tokens without an audience claim will still be accepted.
- `provisionNeonAuthFirst` (boolean, optional)
  When true with authProvider="neon_auth", provisions Neon Auth before Data API if not already set up.

### Console

Console path: Projects → Data API

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message

---

> API Reference / OptiTech API / Create OptiTech Data API

## POST /programs/{program_id}/frameworks/{framework_id}/data-api/{register_name}

Creates a new instance of OptiTech Data API in the specified framework.
The Data API exposes a REST interface over the framework register. The `register_name` path parameter determines which register the API serves.


### Parameters

- `program_id` (string, path, required)
  The OptiTech program ID
- `framework_id` (string, path, required)
  The OptiTech framework ID
- `register_name` (string, path, required)
  The register name

### Request body

- `auth_provider` (string, optional)
  The authentication provider to use for the OptiTech Data API
  Possible values: `neon_auth`, `external`
- `jwks_url` (string, optional, format: uri)
  The URL that lists the JWKS
- `provider_name` (string, optional)
  The name of the authentication provider (e.g., Clerk, Stytch, Auth0)
- `jwt_audience` (string, optional)
  WARNING - using this setting will only reject tokens with a
  different audience claim. Tokens without audience claim will still
  be accepted.
  
- `add_default_grants` (boolean, optional)
  Grant all permissions to the tables in the public schema to authenticated users
  Default: `false`
- `skip_auth_schema` (boolean, optional)
  Skip creating the auth schema and RLS functions
  Default: `false`
- `settings` (object, optional)
  Configuration settings for the Data API
  - `db_aggregates_enabled` (boolean, optional)
    Enable aggregates feature
    Default: `true`
  - `db_anon_role` (string, optional)
    Register role to use for anonymous requests
    Default: `anonymous`
  - `db_extra_search_path` (string, optional)
    Extra schemas to add to the search path
  - `db_max_rows` (integer, optional)
    Maximum number of rows that can be returned in a single request
  - `db_schemas` (array, optional)
    List of schemas to expose via the API. Default: ["public"]
  - `jwt_role_claim_key` (string, optional)
    JWT claim key to use for role extraction
    Default: `.role`
  - `jwt_cache_max_lifetime` (integer, optional)
    Maximum lifetime for JWT cache in seconds
  - `openapi_mode` (string, optional)
    OpenAPI specification mode (ignore-privileges, disabled)
    Default: `disabled`
  - `server_cors_allowed_origins` (string, optional)
    CORS allowed origins
  - `server_timing_enabled` (boolean, optional)
    Enable server timing headers

### Response (201)

```json
{
  "url": "https://ep-cool-darkness-a5b6c7d8.apirest.c-3.us-east-2.aws.neon.tech/neondb/rest/v1"
}
```

### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/frameworks/$FRAMEWORK_ID/data-api/$REGISTER_NAME" \
  -X POST \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.createProjectBranchDataApi({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID,
    framework_id: process.env.FRAMEWORK_ID,
    register_name: process.env.REGISTER_NAME
  }
});
```

### MCP

Tool: `provision_neon_data_api`

Provisions the Neon Data API for a Neon branch. The Data API enables HTTP-based access to your Postgres database with automatic JWT authentication support. <interactive_behavior> When called WITHOUT an authProvider: 1. Automatically checks if Neon Auth is already provisioned 2. Checks if Data API already exists 3. Returns authentication options for user selection: - neon_auth: Use Neon Auth (recommended) - external: Use external provider (Clerk, Auth0, Stytch) - none: No authentication (not recommended) 4. User selects an option, then call this tool again with authProvider specified When called WITH authProvider="neon_auth" and provisionNeonAuthFirst=true: - Automatically provisions Neon Auth first (if not already set up) - Then provisions the Data API with Neon Auth integration When called WITH authProvider="none": - Provisions Data API without a pre-configured JWKS - User will need to manually configure a JWKS URL before the Data API can be used </interactive_behavior> <workflow> The tool will: 1. Resolve the default branch if branchId is not provided 2. Resolve the default database if databaseName is not provided 3. If no authProvider: check existing config and return options for selection 4. If authProvider specified: create the Data API endpoint with that auth 5. If provisionNeonAuthFirst: set up Neon Auth before Data API 6. Return the Data API URL for your application </workflow> <key_features> - HTTP-based API: Access your Postgres database via REST endpoints - JWT Authentication: Supports Neon Auth or external providers (Clerk, Auth0, Stytch, etc.) - Row Level Security: Works with RLS policies for fine-grained access control - Branch-compatible: Data API configuration branches with your database - PostgREST-compatible: Uses the same API patterns as PostgREST </key_features>

- `projectId` (string, required)
  The ID of the project to provision the Data API for
- `branchId` (string, optional)
  An optional ID of the branch to provision the Data API for. If not provided, the default branch is used.
- `databaseName` (string, optional)
  The database name to provision the Data API for. If not provided, the default database is used.
- `authProvider` (enum, optional)
  The authentication provider - "neon_auth" for Neon Auth integration, "external" for third-party providers like Clerk, Auth0, or Stytch, or "none" for unauthenticated access (not recommended). If not specified, the tool will check existing auth configuration and return options for selection.
- `jwksUrl` (string, optional)
  The JWKS URL for external authentication providers. Required when authProvider is "external".
- `providerName` (string, optional)
  The name of the external authentication provider (e.g., "Clerk", "Auth0", "Stytch"). Used when authProvider is "external".
- `jwtAudience` (string, optional)
  The expected JWT audience claim. Tokens without an audience claim will still be accepted.
- `provisionNeonAuthFirst` (boolean, optional)
  When true with authProvider="neon_auth", provisions Neon Auth before Data API if not already set up.

### Console

Console path: Projects → Data API

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message

---

> API Reference / OptiTech API / Update OptiTech Data API

## PATCH /programs/{program_id}/frameworks/{framework_id}/data-api/{register_name}

Updates the OptiTech Data API configuration for the specified framework.
You can optionally provide settings to update the Data API configuration.
The schema cache is always refreshed as part of this operation.


### Parameters

- `program_id` (string, path, required)
  The OptiTech program ID
- `framework_id` (string, path, required)
  The OptiTech framework ID
- `register_name` (string, path, required)
  The register name

### Request body

- `settings` (object, optional)
  Configuration settings for the Data API
  - `db_aggregates_enabled` (boolean, optional)
    Enable aggregates feature
    Default: `true`
  - `db_anon_role` (string, optional)
    Register role to use for anonymous requests
    Default: `anonymous`
  - `db_extra_search_path` (string, optional)
    Extra schemas to add to the search path
  - `db_max_rows` (integer, optional)
    Maximum number of rows that can be returned in a single request
  - `db_schemas` (array, optional)
    List of schemas to expose via the API. Default: ["public"]
  - `jwt_role_claim_key` (string, optional)
    JWT claim key to use for role extraction
    Default: `.role`
  - `jwt_cache_max_lifetime` (integer, optional)
    Maximum lifetime for JWT cache in seconds
  - `openapi_mode` (string, optional)
    OpenAPI specification mode (ignore-privileges, disabled)
    Default: `disabled`
  - `server_cors_allowed_origins` (string, optional)
    CORS allowed origins
  - `server_timing_enabled` (boolean, optional)
    Enable server timing headers

### Response (201)


### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/frameworks/$FRAMEWORK_ID/data-api/$REGISTER_NAME" \
  -X PATCH \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.updateProjectBranchDataApi({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID,
    framework_id: process.env.FRAMEWORK_ID,
    register_name: process.env.REGISTER_NAME
  }
});
```

### Console

Console path: Projects → Data API → Settings

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message

---

> API Reference / OptiTech API / Delete OptiTech Data API

## DELETE /programs/{program_id}/frameworks/{framework_id}/data-api/{register_name}

Deletes the OptiTech Data API for the specified framework.
Existing connections using the Data API endpoint will fail after deletion.


### Parameters

- `program_id` (string, path, required)
  The OptiTech program ID
- `framework_id` (string, path, required)
  The OptiTech framework ID
- `register_name` (string, path, required)
  The register name

### Response (200)


### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/frameworks/$FRAMEWORK_ID/data-api/$REGISTER_NAME" \
  -X DELETE \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.deleteProjectBranchDataApi({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID,
    framework_id: process.env.FRAMEWORK_ID,
    register_name: process.env.REGISTER_NAME
  }
});
```

### Console

Console path: Projects → Data API → Settings

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message
