> Source: https://wexa.ai/docs/connectors/import-connector-spec

# import-connector-spec

Turn an OpenAPI (3.x) or Swagger (2.0) document into a user-defined connector's definition. Nothing is saved. Needs the `fabric:skill.write` grant.

**Import an OpenAPI document**

**Wexa MCP server**

```bash
curl -sS -X POST https://fabric.wexa.ai/mcp/$FABRIC_PROJECT_ID \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "Mcp-Session-Id: $MCP_SESSION_ID" \
  -H "content-type: application/json" -H "accept: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"import-connector-spec","arguments":{"spec":{"openapi":"3.0.0","info":{"title":"Payroll","version":"1.0"},"servers":[{"url":"https://payroll.example.com/v1"}],"paths":{"/employees/{employee_id}":{"get":{"operationId":"get_employee","summary":"Get employee"}}}},"name":"Payroll"}}}'
```

```json
{
  "content": [
    {
      "type": "text",
      "text": "{\"lifecycle_id\":\"qlc_000017\",\"result\":{\"success\":true,\"definition\":{\"name\":\"Payroll\",\"mode\":\"live\",\"base_url\":\"https://payroll.example.com/v1\",\"actions\":[{\"key\":\"get_employee\",\"name\":\"Get employee\",\"request\":{\"method\":\"GET\",\"path\":\"/employees/{employee_id}\"}}]}}}"
    }
  ],
  "isError": false
}
```

**REST API**

```bash
curl -sS https://fabric.wexa.ai/v1/import-connector-spec \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "content-type: application/json" \
  -d '{"spec":{"openapi":"3.0.0","info":{"title":"Payroll","version":"1.0"},"servers":[{"url":"https://payroll.example.com/v1"}],"paths":{"/employees/{employee_id}":{"get":{"operationId":"get_employee","summary":"Get employee"}}}},"name":"Payroll"}'
```

```json
{
  "lifecycle_id": "qlc_000017",
  "result": {
    "success": true,
    "definition": {
      "name": "Payroll",
      "mode": "live",
      "base_url": "https://payroll.example.com/v1",
      "actions": [
        {
          "key": "get_employee",
          "name": "Get employee",
          "request": {
            "method": "GET",
            "path": "/employees/{employee_id}"
          }
        }
      ]
    }
  }
}
```

**TypeScript SDK**

```ts
import { Fabric } from '@wexa-fabric/sdk'

const fabric = new Fabric()
const result = await fabric.importConnectorSpec({
  spec: {
    openapi: '3.0.0',
    info: {
      title: 'Payroll',
      version: '1.0'
    },
    servers: [
      {
        url: 'https://payroll.example.com/v1'
      }
    ],
    paths: {
      '/employees/{employee_id}': {
        get: {
          operationId: 'get_employee',
          summary: 'Get employee'
        }
      }
    }
  },
  name: 'Payroll'
})
```

```ts
// result is the payload itself, with no `.result` to read
{
  success: true,
  definition: {
    name: 'Payroll',
    mode: 'live',
    base_url: 'https://payroll.example.com/v1',
    actions: [
      {
        key: 'get_employee',
        name: 'Get employee',
        request: {
          method: 'GET',
          path: '/employees/{employee_id}'
        }
      }
    ]
  }
}
```

**Python SDK**

```python
from wexa import Fabric

fabric = Fabric()
out = fabric.import_connector_spec(
    spec={
        "openapi": "3.0.0",
        "info": {
            "title": "Payroll",
            "version": "1.0"
        },
        "servers": [
            {
                "url": "https://payroll.example.com/v1"
            }
        ],
        "paths": {
            "/employees/{employee_id}": {
                "get": {
                    "operationId": "get_employee",
                    "summary": "Get employee"
                }
            }
        }
    },
    name="Payroll",
)
```

```python
# out is the result, already unwrapped
{
    "success": True,
    "definition": {
        "name": "Payroll",
        "mode": "live",
        "base_url": "https://payroll.example.com/v1",
        "actions": [
            {
                "key": "get_employee",
                "name": "Get employee",
                "request": {
                    "method": "GET",
                    "path": "/employees/{employee_id}"
                }
            }
        ]
    }
}
```

## Parameters

| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| `spec` | object | Required | The parsed OpenAPI or Swagger document: an object, not a URL or a string. A document the platform cannot turn into a valid definition is refused (422), with its own reason. |
| `name` | string | Optional | The connector's name. |

**Show full response**

An example response, for the one-operation document in the call below. The fields inside each action's schemas depend on the document.

**Result of import-connector-spec**

**REST API**

```json
{
  "lifecycle_id": "qlc_000017",
  "result": {
    "success": true,
    "definition": {
      "name": "Payroll",
      "description": "",
      "logo": null,
      "mode": "live",
      "base_url": "https://payroll.example.com/v1",
      "auth": {
        "type": "none",
        "name": null,
        "location": "header"
      },
      "headers": {},
      "actions": [
        {
          "key": "get_employee",
          "name": "Get employee",
          "description": "",
          "input_schema": null,
          "output_schema": {
            "fields": []
          },
          "fault": null,
          "request": {
            "method": "GET",
            "path": "/employees/{employee_id}",
            "query": [],
            "headers": {},
            "body": "none",
            "result_path": null
          }
        }
      ]
    }
  }
}
```

**Wexa MCP server**

```json
{
  "content": [
    {
      "type": "text",
      "text": "{\"lifecycle_id\":\"qlc_000017\",\"result\":{\"success\":true,\"definition\":{\"name\":\"Payroll\",\"description\":\"\",\"logo\":null,\"mode\":\"live\",\"base_url\":\"https://payroll.example.com/v1\",\"auth\":{\"type\":\"none\",\"name\":null,\"location\":\"header\"},\"headers\":{},\"actions\":[{\"key\":\"get_employee\",\"name\":\"Get employee\",\"description\":\"\",\"input_schema\":null,\"output_schema\":{\"fields\":[]},\"fault\":null,\"request\":{\"method\":\"GET\",\"path\":\"/employees/{employee_id}\",\"query\":[],\"headers\":{},\"body\":\"none\",\"result_path\":null}}]}}}"
    }
  ],
  "isError": false
}
```

**TypeScript SDK**

```ts
// the object you get back IS the result — there is no `.result` to read
{
  "success": true,
  "definition": {
    "name": "Payroll",
    "description": "",
    "logo": null,
    "mode": "live",
    "base_url": "https://payroll.example.com/v1",
    "auth": {
      "type": "none",
      "name": null,
      "location": "header"
    },
    "headers": {},
    "actions": [
      {
        "key": "get_employee",
        "name": "Get employee",
        "description": "",
        "input_schema": null,
        "output_schema": {
          "fields": []
        },
        "fault": null,
        "request": {
          "method": "GET",
          "path": "/employees/{employee_id}",
          "query": [],
          "headers": {},
          "body": "none",
          "result_path": null
        }
      }
    ]
  }
}

// The TS SDK names these camelCase — lifecycleId, traceId — where Python uses
// lifecycle_id and trace_id. Both are non-enumerable: readable, but omitted by
// Object.keys() and JSON.stringify(). `result.lifecycleId` here is undefined.
result.lifecycleId // 'qlc_000017'
```

**Python SDK**

```python
# a dict subclass; `result` is already unwrapped
{
 "success": True,
 "definition": {
  "name": "Payroll",
  "description": "",
  "logo": None,
  "mode": "live",
  "base_url": "https://payroll.example.com/v1",
  "auth": {
   "type": "none",
   "name": None,
   "location": "header"
  },
  "headers": {},
  "actions": [
   {
    "key": "get_employee",
    "name": "Get employee",
    "description": "",
    "input_schema": None,
    "output_schema": {
     "fields": []
    },
    "fault": None,
    "request": {
     "method": "GET",
     "path": "/employees/{employee_id}",
     "query": [],
     "headers": {},
     "body": "none",
     "result_path": None
    }
   }
  ]
 }
}

out.lifecycle_id  # 'qlc_000017' — an attribute, not a key
```

Keeping the `lifecycle_id` is what lets you ask later why a call was allowed, refused or held.

**More details**

**Response fields**

- `success`: `true`.
- `definition`: The drafted definition: `name`, `description`, `mode`, `base_url`, `auth`, `headers` and `actions`, the same shape `save-user-connector` takes.

The definition has one action per operation, each with its request (method, path, query and body), the base URL from the document's servers, and the auth scheme from its security schemes. The fields inside each action's schemas depend on the document.

Nothing is saved. Read the definition, change what you need, and pass it to [`save-user-connector`](/docs/connectors/save-user-connector) to keep it as a draft.

Saves nothing, so not marked consequential: it is audited lightly and is never held for approval. It needs `fabric:skill.write` because it is the first step of building a connector.

Every tool call works the same way: [How every tool call works](/docs/sdks-and-apis/how-every-tool-call-works).
