# Structurely Direct v2

## Overview

The Structurely API allows integrators to provide automation for their accounts. It offers various functionalities to streamline lead management, messaging, lead qualification conversations, and retrieval of metadata.

The Structurely API simplifies the integration process and removes the necessity to track additional fields in your system. It is specifically designed to utilize **your system's IDs** as internal keys, enabling you to seamlessly use IDs from your CRM or database as parameters, such as externalLeadId, and externalMessageId.

By utilizing this API, integrators can streamline their workflows, activate enhanced AI qualification conversations, and gain valuable insights into their accounts, leads, and conversations.

### Security

The Structurely API provides secure authentication and authorization mechanisms to ensure controlled access to its endpoints. The authentication system utilizes API tokens to secure interactions with the API.

Types of tokens and keys:

  
- bearer-access-token: Bearer JWT; **valid until deactivated**

**Note:** It is essential to keep your bearer-access-tokens secure and avoid sharing them with unauthorized parties to maintain the integrity and security of your Structurely API integration.

Version: `v3.35.20`

## Channels

- [GET /api/direct/v2/channels](/api/direct/v2/channels/get.md)
- [PATCH /api/direct/v2/channels/{channelId}](/api/direct/v2/channels/{channelId}/patch.md)

### GET /api/direct/v2/channels

[GET /api/direct/v2/channels](/api/direct/v2/channels/get.md)

**Summary:** List SMS channels

**Description:**

List SMS channels owned directly by the authenticated entity. Requires channel:read or channel:write. Results are sorted by ascending channel ID and use opaque cursor pagination.

#### Parameters

- `limit` (query, required: no)
  - Number of channels to return. Defaults to 50 and must be between 1 and 100.
  - Schema:
    ```json
    {
      "type": "integer"
    }
    ```
- `cursor` (query, required: no)
  - Opaque padded URL-safe base64 cursor from a previous response.
  - Schema:
    ```json
    {
      "type": "string"
    }
    ```

#### Responses

- `200`: Cursor-paginated SMS channels for the authenticated entity.
  - Schema: `ChannelListResponse`
  ```json
  {
    "type": "object",
    "properties": {
      "items": {
        "type": "array",
        "description": "Cursor-paginated SMS channels.",
        "items": {
          "$ref": "#/components/schemas/Channel"
        }
      },
      "cursor": {
        "type": "string",
        "description": "Opaque cursor for the next page, or null when complete.",
        "nullable": true
      },
      "next": {
        "type": "string",
        "description": "Fully-qualified URL for the next page, or null when complete.",
        "nullable": true
      }
    },
    "required": [
      "cursor",
      "items",
      "next"
    ]
  }
  ```
- `400`: Invalid request, check response message
  - Schema: `InvalidRequest`
  ```json
  {
    "type": "object",
    "properties": {
      "message": {
        "type": "string",
        "description": "A message describing the error",
        "example": "The parameter leadId must be provided"
      },
      "statusCode": {
        "type": "number",
        "example": 400
      }
    }
  }
  ```
- `401`: Request is not authorized
  - Schema: `NotAuthorized`
  ```json
  {
    "type": "object",
    "properties": {
      "message": {
        "type": "string",
        "description": "A message describing the error",
        "example": "Access Token is not authorized"
      },
      "statusCode": {
        "type": "number",
        "example": 401
      }
    }
  }
  ```
- `500`: Internal server error, check response message
  - Schema: `InternalServerError`
  ```json
  {
    "type": "object",
    "properties": {
      "message": {
        "type": "string",
        "description": "A message describing the error",
        "example": "Internal server error"
      },
      "statusCode": {
        "type": "number",
        "example": 500
      }
    }
  }
  ```

#### Security

- `bearer-access-token`

#### Example request

```bash
curl -sS -X GET 'https://client.structurely.com/api/direct/v2/channels' \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $STRUCTURELY_API_TOKEN"
```

### PATCH /api/direct/v2/channels/{channelId}

[PATCH /api/direct/v2/channels/{channelId}](/api/direct/v2/channels/{channelId}/patch.md)

**Summary:** Update SMS channel assignments

**Description:**

Assign or clear a Campaign or Voice AI Agent for an SMS channel owned directly by the authenticated entity. Requires channel:write. Omitted fields remain unchanged; explicit null clears the corresponding assignment. A Campaign and Voice AI Agent cannot both be assigned in the same request.

#### Parameters

- `channelId` (path, required: yes)
  - The SMS channel ID.
  - Schema:
    ```json
    {
      "oneOf": [
        {
          "format": "ObjectId",
          "type": "string"
        }
      ]
    }
    ```

#### Request body

Optional nullable Campaign and Voice AI Agent assignment IDs.

Schema: `PatchChannel`

```json
{
  "type": "object",
  "properties": {
    "campaignId": {
      "description": "Campaign ID to assign, or null to clear the Campaign assignment.",
      "type": "string",
      "format": "ObjectId",
      "nullable": true
    },
    "voiceAgentId": {
      "description": "Voice AI Agent ID to assign, or null to clear the Voice AI Agent assignment.",
      "type": "string",
      "format": "ObjectId",
      "nullable": true
    }
  }
}
```

#### Responses

- `200`: The complete updated SMS channel resource.
  - Schema: `Channel`
  ```json
  {
    "type": "object",
    "properties": {
      "id": {
        "type": "string",
        "description": "SMS channel ID.",
        "example": "650ba6ced07cb5552a2467b0",
        "format": "ObjectId"
      },
      "channelType": {
        "type": "string",
        "enum": [
          "SMS"
        ],
        "description": "Channel type.",
        "example": "SMS"
      },
      "address": {
        "type": "string",
        "description": "SMS source address.",
        "example": "+13035555555"
      },
      "enabled": {
        "type": "boolean",
        "description": "Whether the channel is active.",
        "example": true
      },
      "campaignId": {
        "type": "string",
        "description": "Assigned Campaign ID, or null when no Campaign is assigned.",
        "format": "ObjectId",
        "nullable": true
      },
      "voiceAgentId": {
        "type": "string",
        "description": "Assigned Voice AI Agent ID, or null when no Voice AI Agent is assigned.",
        "format": "ObjectId",
        "nullable": true
      }
    },
    "required": [
      "address",
      "campaignId",
      "channelType",
      "enabled",
      "id",
      "voiceAgentId"
    ]
  }
  ```
- `400`: Invalid request, check response message
  - Schema: `InvalidRequest`
  ```json
  {
    "type": "object",
    "properties": {
      "message": {
        "type": "string",
        "description": "A message describing the error",
        "example": "The parameter leadId must be provided"
      },
      "statusCode": {
        "type": "number",
        "example": 400
      }
    }
  }
  ```
- `401`: Request is not authorized
  - Schema: `NotAuthorized`
  ```json
  {
    "type": "object",
    "properties": {
      "message": {
        "type": "string",
        "description": "A message describing the error",
        "example": "Access Token is not authorized"
      },
      "statusCode": {
        "type": "number",
        "example": 401
      }
    }
  }
  ```
- `404`: Resource was not found, check response message
  - Schema: `NotFound`
  ```json
  {
    "type": "object",
    "properties": {
      "message": {
        "type": "string",
        "description": "A message describing the error",
        "example": "Lead not found"
      },
      "statusCode": {
        "type": "number",
        "example": 404
      }
    }
  }
  ```
- `500`: Internal server error, check response message
  - Schema: `InternalServerError`
  ```json
  {
    "type": "object",
    "properties": {
      "message": {
        "type": "string",
        "description": "A message describing the error",
        "example": "Internal server error"
      },
      "statusCode": {
        "type": "number",
        "example": 500
      }
    }
  }
  ```

#### Security

- `bearer-access-token`

#### Example request

```bash
curl -sS -X PATCH 'https://client.structurely.com/api/direct/v2/channels/{channelId}' \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $STRUCTURELY_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
```

## Schemas

### `Channel`

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "SMS channel ID.",
      "example": "650ba6ced07cb5552a2467b0",
      "format": "ObjectId"
    },
    "channelType": {
      "type": "string",
      "enum": [
        "SMS"
      ],
      "description": "Channel type.",
      "example": "SMS"
    },
    "address": {
      "type": "string",
      "description": "SMS source address.",
      "example": "+13035555555"
    },
    "enabled": {
      "type": "boolean",
      "description": "Whether the channel is active.",
      "example": true
    },
    "campaignId": {
      "type": "string",
      "description": "Assigned Campaign ID, or null when no Campaign is assigned.",
      "format": "ObjectId",
      "nullable": true
    },
    "voiceAgentId": {
      "type": "string",
      "description": "Assigned Voice AI Agent ID, or null when no Voice AI Agent is assigned.",
      "format": "ObjectId",
      "nullable": true
    }
  },
  "required": [
    "address",
    "campaignId",
    "channelType",
    "enabled",
    "id",
    "voiceAgentId"
  ]
}
```

### `ChannelListResponse`

```json
{
  "type": "object",
  "properties": {
    "items": {
      "type": "array",
      "description": "Cursor-paginated SMS channels.",
      "items": {
        "$ref": "#/components/schemas/Channel"
      }
    },
    "cursor": {
      "type": "string",
      "description": "Opaque cursor for the next page, or null when complete.",
      "nullable": true
    },
    "next": {
      "type": "string",
      "description": "Fully-qualified URL for the next page, or null when complete.",
      "nullable": true
    }
  },
  "required": [
    "cursor",
    "items",
    "next"
  ]
}
```

### `InternalServerError`

```json
{
  "type": "object",
  "properties": {
    "message": {
      "type": "string",
      "description": "A message describing the error",
      "example": "Internal server error"
    },
    "statusCode": {
      "type": "number",
      "example": 500
    }
  }
}
```

### `InvalidRequest`

```json
{
  "type": "object",
  "properties": {
    "message": {
      "type": "string",
      "description": "A message describing the error",
      "example": "The parameter leadId must be provided"
    },
    "statusCode": {
      "type": "number",
      "example": 400
    }
  }
}
```

### `NotAuthorized`

```json
{
  "type": "object",
  "properties": {
    "message": {
      "type": "string",
      "description": "A message describing the error",
      "example": "Access Token is not authorized"
    },
    "statusCode": {
      "type": "number",
      "example": 401
    }
  }
}
```

### `NotFound`

```json
{
  "type": "object",
  "properties": {
    "message": {
      "type": "string",
      "description": "A message describing the error",
      "example": "Lead not found"
    },
    "statusCode": {
      "type": "number",
      "example": 404
    }
  }
}
```

### `PatchChannel`

```json
{
  "type": "object",
  "properties": {
    "campaignId": {
      "description": "Campaign ID to assign, or null to clear the Campaign assignment.",
      "type": "string",
      "format": "ObjectId",
      "nullable": true
    },
    "voiceAgentId": {
      "description": "Voice AI Agent ID to assign, or null to clear the Voice AI Agent assignment.",
      "type": "string",
      "format": "ObjectId",
      "nullable": true
    }
  }
}
```

## Security

### `bearer-access-token`

```json
{
  "type": "http",
  "scheme": "bearer",
  "bearerFormat": "JWT"
}
```
