> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended**:
> ```bash
> npx @scalekit-inc/cli setup
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Create a custom connector

`POST /api/v1/custom-providers`

Creates an environment-scoped custom provider (connector) with authentication patterns and optional proxy configuration. The returned identifier must be used for all subsequent update and delete operations on this provider.

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `auth_patterns` | array of object | Yes | Authentication patterns for the connected app provider. |
| `auth_patterns.display_name` | string | Yes | Name of the method, shown to the user while they connect. |
| `auth_patterns.type` | string (enum) | Yes | How users authenticate. Use `NO_AUTH` only for a public MCP server, with `is_mcp` set and no `fields`. The `type` of an existing pattern can't change. One of: `OAUTH`, `BEARER`, `API_KEY`, `BASIC`, `NO_AUTH`. |
| `auth_patterns.account_fields` | array of object | No | Inputs collected for an `OAUTH` pattern, such as a value `proxy_url` needs. Same fields as `fields`. |
| `auth_patterns.auth_field_mutations` | object | No | A `prefix`, `suffix` or `default` applied to a credential before Scalekit sends it, keyed by `api_key`, `token`, `username` or `password`. |
| `auth_patterns.auth_header_key_override` | string | No | Header to send the credential in when the app doesn't use `Authorization`, such as `X-API-Key`. |
| `auth_patterns.description` | string | No | Short explanation of the method. |
| `auth_patterns.fields` | array of object | No | Inputs the user fills in for `BEARER`, `API_KEY` and `BASIC`. Leave it empty for `OAUTH` and `NO_AUTH`. |
| `auth_patterns.fields.field_name` | string | Yes | Key the value is stored under: `token` for `BEARER`, `api_key` for `API_KEY`, `username` and `password` for `BASIC`, or a name such as `domain` that `proxy_url` uses as `{{domain}}`. |
| `auth_patterns.fields.hint` | string | No | Helper text shown with the input. |
| `auth_patterns.fields.input_type` | string (enum) | No | Use `password` for secrets, so the input is masked. One of: `text`, `password`, `select`. |
| `auth_patterns.fields.label` | string | No | Label shown above the input. |
| `auth_patterns.fields.options` | array of object | No | Choices for a `select` input, each with `value`, `display_name`, `description` and `default`. |
| `auth_patterns.fields.required` | boolean | No | Whether the user must fill in the input before connecting. |
| `auth_patterns.is_mcp` | boolean | No | Set to `true` when `proxy_url` is an MCP server. Set it on every pattern; it can't change later. |
| `auth_patterns.oauth_config` | object | No | OAuth settings for an `OAUTH` pattern. For an MCP server, `{"pkce_enabled": true}` is enough: the server handles authorization. |
| `auth_patterns.oauth_config.authorize_uri` | string | No | The app's authorization endpoint. |
| `auth_patterns.oauth_config.available_scopes` | array of object | No | Scopes the connection can request, each with `scope`, `display_name`, `description` and `required`. |
| `auth_patterns.oauth_config.pkce_enabled` | boolean | No | Whether the authorization flow uses PKCE. |
| `auth_patterns.oauth_config.token_uri` | string | No | The app's token endpoint. |
| `auth_patterns.oauth_config.user_info_uri` | string | No | Endpoint that returns the signed-in user. |
| `display_name` | string | Yes | Display name for the connected app provider. |
| `proxy_url` | string | Yes | Proxy URL for the connected app provider. Must start with https://. |
| `description` | string | No | Description of the connected app provider. |
| `icon_src` | string | No | URL for the provider icon. Should be an SVG image sized 800x800 pixels for best rendering experience. |
| `metadata` | object | No | Custom key-value metadata for this provider. Keys must be 3-25 characters, values must be 1-256 characters, with a maximum of 20 key-value pairs. |
| `proxy_enabled` | boolean | No | This flag indicates whether proxying is turned on for the connected app provider. When enabled, requests are routed through the provider proxy instead of being sent directly. |

**Response (200)**

| Name | Type | Description |
| --- | --- | --- |
| `provider` | object | The connector. |
| `provider.auth_patterns` | array of object | How users authenticate, as sent in the request. |
| `provider.auth_patterns.account_fields` | array of object | Inputs collected for an `OAUTH` pattern, such as a value `proxy_url` needs. Same fields as `fields`. |
| `provider.auth_patterns.auth_field_mutations` | object | A `prefix`, `suffix` or `default` applied to a credential before Scalekit sends it, keyed by `api_key`, `token`, `username` or `password`. |
| `provider.auth_patterns.auth_header_key_override` | string | Header to send the credential in when the app doesn't use `Authorization`, such as `X-API-Key`. |
| `provider.auth_patterns.description` | string | Short explanation of the method. |
| `provider.auth_patterns.display_name` | string | Name of the method, shown to the user while they connect. |
| `provider.auth_patterns.fields` | array of object | Inputs the user fills in for `BEARER`, `API_KEY` and `BASIC`. Leave it empty for `OAUTH` and `NO_AUTH`. |
| `provider.auth_patterns.fields.field_name` | string | Key the value is stored under: `token` for `BEARER`, `api_key` for `API_KEY`, `username` and `password` for `BASIC`, or a name such as `domain` that `proxy_url` uses as `{{domain}}`. |
| `provider.auth_patterns.fields.hint` | string | Helper text shown with the input. |
| `provider.auth_patterns.fields.input_type` | string (enum) | Use `password` for secrets, so the input is masked. One of: `text`, `password`, `select`. |
| `provider.auth_patterns.fields.label` | string | Label shown above the input. |
| `provider.auth_patterns.fields.options` | array of object | Choices for a `select` input, each with `value`, `display_name`, `description` and `default`. |
| `provider.auth_patterns.fields.required` | boolean | Whether the user must fill in the input before connecting. |
| `provider.auth_patterns.is_mcp` | boolean | Set to `true` when `proxy_url` is an MCP server. Set it on every pattern; it can't change later. |
| `provider.auth_patterns.oauth_config` | object | OAuth settings for an `OAUTH` pattern. For an MCP server, `{"pkce_enabled": true}` is enough: the server handles authorization. |
| `provider.auth_patterns.oauth_config.authorize_uri` | string | The app's authorization endpoint. |
| `provider.auth_patterns.oauth_config.available_scopes` | array of object | Scopes the connection can request, each with `scope`, `display_name`, `description` and `required`. |
| `provider.auth_patterns.oauth_config.pkce_enabled` | boolean | Whether the authorization flow uses PKCE. |
| `provider.auth_patterns.oauth_config.token_uri` | string | The app's token endpoint. |
| `provider.auth_patterns.oauth_config.user_info_uri` | string | Endpoint that returns the signed-in user. |
| `provider.auth_patterns.type` | string (enum) | How users authenticate. Use `NO_AUTH` only for a public MCP server, with `is_mcp` set and no `fields`. The `type` of an existing pattern can't change. One of: `OAUTH`, `BEARER`, `API_KEY`, `BASIC`, `NO_AUTH`. |
| `provider.categories` | array of string | Catalog categories. Empty for a custom connector. |
| `provider.coming_soon` | boolean | Whether the catalog lists the connector as coming soon. |
| `provider.description` | string | Short description of the app. |
| `provider.display_name` | string | Name shown to users. |
| `provider.display_priority` | integer | Where the connector sorts in lists; lower numbers come first. |
| `provider.icon_src` | string | URL of the connector's icon. |
| `provider.id` | string | Scalekit's ID for the connector. |
| `provider.identifier` | string | Pass it to update and delete the connector. Scalekit derives it from `display_name`. |
| `provider.is_custom` | boolean | Indicates whether the provider is environment-scoped (custom provider). |
| `provider.is_custom_mcp` | boolean | Indicates whether this is an environment-scoped MCP-based custom provider. |
| `provider.metadata` | object | Custom key-value metadata stored for this provider. Returned for all providers; defaults to {} when no metadata has been set. |
| `provider.proxy_enabled` | boolean | Whether Scalekit proxies requests to `proxy_url`. |
| `provider.proxy_url` | string | Base URL of the API that the proxy calls. |

**Errors**

- `400`: Invalid request - the provider payload failed validation (e.g. missing required fields or invalid proxy URL)

**Request**

```bash
curl -sS -X POST \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/custom-providers" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "Example API",
    "description": "Connect to an API that accepts a static bearer token",
    "auth_patterns": [
      {
        "type": "BEARER",
        "display_name": "Bearer Token",
        "description": "Authenticate with a static bearer token",
        "fields": [
          {
            "field_name": "token",
            "label": "Bearer Token",
            "input_type": "password",
            "hint": "Your long-lived bearer token",
            "required": true
          }
        ]
      }
    ],
    "proxy_url": "https://api.example.com",
    "proxy_enabled": true
  }'
```

**Response**

```json
{
  "provider": {
    "id": "prvd_84718296317953812",
    "identifier": "EXAMPLEAPI:12345",
    "display_name": "Example API",
    "description": "Connect to an API that accepts a static bearer token",
    "auth_patterns": [
      {
        "type": "BEARER",
        "display_name": "Bearer Token",
        "description": "Authenticate with a static bearer token",
        "fields": [
          {
            "field_name": "token",
            "label": "Bearer Token",
            "input_type": "password",
            "hint": "Your long-lived bearer token",
            "required": true
          }
        ]
      }
    ],
    "proxy_url": "https://api.example.com",
    "proxy_enabled": true,
    "categories": [],
    "icon_src": "",
    "display_priority": 1,
    "coming_soon": false,
    "is_custom": true,
    "is_custom_mcp": false,
    "metadata": {}
  }
}
```

**Python SDK:** `scalekit_client.actions.providers.create_custom_provider`

Create a new custom provider.

```python
scalekit_client.actions.providers.create_custom_provider(
    request: CreateCustomProviderRequest,
) -> CreateCustomProviderResponse
```

Example:

```python
from scalekit.actions.types import CreateCustomProviderRequest

result = scalekit_client.actions.providers.create_custom_provider(
    request=CreateCustomProviderRequest(
        display_name="Example API",
        description="Connect to an API that accepts a static bearer token",
        auth_patterns=[
            {
                "type": "BEARER",
                "display_name": "Bearer Token",
                "description": "Authenticate with a static bearer token",
                "fields": [
                    {
                        "field_name": "token",
                        "label": "Bearer Token",
                        "input_type": "password",
                        "hint": "Your long-lived bearer token",
                        "required": True,
                    },
                ],
            },
        ],
        proxy_url="https://api.example.com",
        proxy_enabled=True,
    ),
)
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `request` | `CreateCustomProviderRequest` | Yes | Request object containing display_name (required), proxy_url (required), and optional description, proxy_enabled, auth_patterns, icon_src, and metadata. |

Returns `CreateCustomProviderResponse`: The created provider with its server-assigned identifier and all decoded auth_patterns.

**Node.js SDK:** `scalekit.actions.providers.createCustomProvider`

Creates a custom connector.

```ts
scalekit.actions.providers.createCustomProvider(
  params: {
    displayName: string;
    proxyUrl: string;
    proxyEnabled?: boolean;
    description?: string;
    authPatterns: AuthPattern[];
    iconSrc?: string;
    metadata?: Record<string, string>;
  },
): Promise<CreateProviderResponse>
```

Example:

```ts
const result = await scalekit.actions.providers.createCustomProvider({
  displayName: "Example API",
  proxyUrl: "https://api.example.com",
  proxyEnabled: true,
  description: "Connect to an API that accepts a static bearer token",
  authPatterns: [
    {
      type: "BEARER",
      display_name: "Bearer Token",
      description: "Authenticate with a static bearer token",
      fields: [
        {
          field_name: "token",
          label: "Bearer Token",
          input_type: "password",
          hint: "Your long-lived bearer token",
          required: true,
        },
      ],
    },
  ],
});
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `displayName` | `string` | Yes | Human-readable name. Letters, digits and spaces only. Suffix it with "MCP" when the connector fronts an MCP server. |
| `proxyUrl` | `string` | Yes | Base HTTPS URL of the upstream service. |
| `proxyEnabled` | `boolean` | No | Whether Scalekit proxies requests. Defaults to true. |
| `description` | `string` | No | Description of the connected app provider |
| `authPatterns` | `AuthPattern[]` | Yes | How users authenticate: one pattern, with its `type`, `display_name` and the `fields` users fill in. |
| `iconSrc` | `string` | No | URL for the provider icon. Should be an SVG image sized 800x800 pixels for best rendering experience. |
| `metadata` | `Record<string, string>` | No | Custom key-value metadata for this provider. Keys must be 3-25 characters, values must be 1-256 characters, with a maximum of 20 key-value pairs. |

Returns `Promise<CreateProviderResponse>`: `provider.identifier` on the response is the id you pass to `updateCustomProvider` and `deleteCustomProvider`.

**Used in**

- [Create a connector](https://docs.scalekit.com/agentkit/bring-your-own-connector/create-connector/)


Part of [Custom connectors](https://docs.scalekit.com/agentkit/reference/custom-connectors/) in the [AgentKit API reference](https://docs.scalekit.com/agentkit/reference/). Authentication: https://docs.scalekit.com/agentkit/reference/authentication.md. Errors and rate limits: https://docs.scalekit.com/agentkit/reference/errors.md. Pagination: https://docs.scalekit.com/agentkit/reference/pagination.md


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
