> ## Documentation Index
> Fetch the complete documentation index at: https://docs.onyx.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Connectors

> Learn how to create and configure connectors programmatically

<Tip>
  This is an advanced guide for automating connector creation.
  We highly recommend trying the Admin Panel or File Ingestion API first.
</Tip>

To see available connectors, see the [Connectors page](/admins/connectors).

## Guide

Skip to the [Full Code](#full-code) section if you don't want the step-by-step guide.

In this example, we'll automate creating Jira Connectors for a selection of projects.

**You will need an Admin API key to follow this guide.**

<Steps>
  <Step title="Prepare your request">
    <CodeGroup>
      ```python Python theme={null}
      import requests

      API_BASE_URL = "https://cloud.onyx.app/api"   # or your own domain
      API_KEY = "YOUR_KEY_HERE"

      headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json"
      }
      ```

      ```bash Shell theme={null}
      API_BASE_URL="https://cloud.onyx.app/api"
      API_KEY="YOUR_KEY_HERE"
      ```
    </CodeGroup>
  </Step>

  <Step title="Prepare your ConnectorSpecificConfig">
    Each Connector type has a different `ConnectorSpecificConfig`. To find the correct configuration,
    find your relevant Connector in
    [`backend/onyx/connectors/`](https://github.com/onyx-dot-app/onyx/tree/main/backend/onyx/connectors).

    For Jira, since we're indexing a selection of projects, rather than all projects,
    we'll need to specify `jira_base_url`, `project_key`, and optionally `comment_email_blacklist`.

    ```json JSON theme={null}
    {
      "jira_base_url": "string",
      "project_key": "string | null",
      "comment_email_blacklist": ["string"] | null
    }
    ```

    <Note>
      The `ConnectorSpecificConfig` are the same fields you fill out in the Admin Panel when creating a Connector.
    </Note>
  </Step>

  <Step title="Prepare your Connector payload">
    In addition to the `ConnectorSpecificConfig`,
    we also need to satisfy the schema for the `ConnectorUpdateRequest` object. See [Core Concepts:
    Connectors](/developers/core_concepts#connectors) for more details.

    In this example, we'll set the `access_type`, `name`, `source`, `input_type`, `refresh_freq`, and `prune_freq`.

    <CodeGroup>
      ```python Python theme={null}
      connector_payload = {
        "name": f"jira-{project_key}",
        "source": "jira",
        "input_type": "poll",
        "access_type": "PUBLIC",
        "connector_specific_config": {
          "jira_base_url": JIRA_BASE_URL,
          "project_key": project_key,
          "comment_email_blacklist": ["legal@company.com"]
        },
        "refresh_freq": 3600,  # Refresh every hour (3600 seconds)
        "prune_freq": 86400,   # Prune every day (86400 seconds)
      }
      ```

      ```json JSON theme={null}
      {
        "name": "jira-TECH",
        "source": "jira",
        "input_type": "poll",
        "access_type": "PUBLIC",
        "connector_specific_config": {
          "jira_base_url": "https://your-company.atlassian.net",
          "project_key": "TECH",
          "comment_email_blacklist": ["legal@company.com"]
        },
        "refresh_freq": 3600,
        "prune_freq": 86400
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="Make the request">
    <Tip>
      Save the Connector ID from the response! You will need this later.
    </Tip>

    <CodeGroup>
      ```python Python expandable theme={null}
      import requests
      import json
      from datetime import datetime

      PROJECTS_TO_INDEX = [
        "TECH",
        "SALES",
        "OPS",
      ]

      JIRA_BASE_URL = "https://your-company.atlassian.net"
      connector_ids = []

      for project_key in PROJECTS_TO_INDEX:
        connector_payload = {
          "name": f"jira-{project_key}",
          "source": "jira",
          "input_type": "poll",
          "access_type": "PUBLIC",
          "connector_specific_config": {
            "jira_base_url": JIRA_BASE_URL,
            "project_key": project_key,
            "comment_email_blacklist": ["legal@company.com"]
          },
          "refresh_freq": 3600,  # Refresh every hour (3600 seconds)
          "prune_freq": 86400,   # Prune every day (86400 seconds)
        }

        response = requests.post(
          f"{API_BASE_URL}/manage/admin/connector",
          headers=headers,
          json=connector_payload
        )

        if response.status_code == 200:
          connector_data = response.json()
          connector_id = connector_data.get('id')
          connector_ids.append(connector_id)
          print(f"Successfully created connector for project {project_key}")
          print(f"Connector ID: {connector_id}")
        else:
          print(f"Failed to create connector for project {project_key}")
          print(f"Status: {response.status_code}")
          print(f"Error: {response.text}")
      ```

      ```bash Shell expandable theme={null}
      # Create connector for TECH project
      curl -X POST "${API_BASE_URL}/manage/admin/connector" \
        -H "Authorization: Bearer ${API_KEY}" \
        -H "Content-Type: application/json" \
        -d '{
          "name": "jira-TECH",
          "source": "jira",
          "input_type": "poll",
          "access_type": "PUBLIC",
          "connector_specific_config": {
            "jira_base_url": "https://your-company.atlassian.net",
            "project_key": "TECH",
            "comment_email_blacklist": ["legal@company.com"]
          },
          "refresh_freq": 3600,
          "prune_freq": 86400
        }'

      # Create connector for SALES project
      curl -X POST "${API_BASE_URL}/manage/admin/connector" \
        -H "Authorization: Bearer ${API_KEY}" \
        -H "Content-Type: application/json" \
        -d '{
          "name": "jira-SALES",
          "source": "jira",
          "input_type": "poll",
          "access_type": "PUBLIC",
          "connector_specific_config": {
            "jira_base_url": "https://your-company.atlassian.net",
            "project_key": "SALES",
            "comment_email_blacklist": ["legal@company.com"]
          },
          "refresh_freq": 3600,
          "prune_freq": 86400
        }'

      # Create connector for OPS project
      curl -X POST "${API_BASE_URL}/manage/admin/connector" \
        -H "Authorization: Bearer ${API_KEY}" \
        -H "Content-Type: application/json" \
        -d '{
          "name": "jira-OPS",
          "source": "jira",
          "input_type": "poll",
          "access_type": "PUBLIC",
          "connector_specific_config": {
            "jira_base_url": "https://your-company.atlassian.net",
            "project_key": "OPS",
            "comment_email_blacklist": ["legal@company.com"]
          },
          "refresh_freq": 3600,
          "prune_freq": 86400
        }'
      ```
    </CodeGroup>
  </Step>

  <Step title="Find your Credentials for the Connector">
    The easiest way to create a Credential is in the Admin Panel.

    * Click Add a Connector
    * Select your relevant Connector
    * Follow the instructions to create a Credential

    Once your Credential is created, the Credential ID will be displayed to you.

    Certain Connectors may not require a Credential such as the File and Web connectors. `credential_id:
            0` is a default empty Credential you can use for these Connectors.

    To list your Credentials, you can use the `GET manage/admin/credential` endpoint.

    <CodeGroup>
      ```python Python theme={null}
      response = requests.get(
        f"{API_BASE_URL}/manage/admin/credential",
        headers=headers
      )

      credentials = response.json()
      jira_credential_id = next(cred for cred in credentials if cred['source'] == 'jira')['id']
      ```

      ```bash Shell theme={null}
      curl -X GET "${API_BASE_URL}/manage/admin/credential" \
        -H "Authorization: Bearer ${API_KEY}" \
        -H "Content-Type: application/json"
      ```
    </CodeGroup>
  </Step>

  <Step title="Associate the Credential with the Connector">
    <Note>
      If you do not do this step, your `Connector` is not fully created and you will not see it in the Admin Panel!
    </Note>

    <CodeGroup>
      ```python Python theme={null}
      for connector_id in connector_ids:
        try:
          response = requests.put(
            f"{API_BASE_URL}/manage/admin/connector/{connector_id}/credential/{jira_credential_id}",
            headers=headers,
          )

          if response.status_code == 200:
            print(f"Successfully associated credential with connector {connector_id}")
          else:
            print(f"Failed to associate credential with connector {connector_id}")
            print(f"Status: {response.status_code}. Error: {response.text}")
        except Exception as e:
          print(f"Failed to associate credential with connector {connector_id}: {e}")
      ```

      ```bash Shell theme={null}
      # Replace CONNECTOR_ID and CREDENTIAL_ID with actual values
      curl -X PUT "${API_BASE_URL}/manage/admin/connector/CONNECTOR_ID/credential/CREDENTIAL_ID" \
        -H "Authorization: Bearer ${API_KEY}" \
        -H "Content-Type: application/json"
      ```
    </CodeGroup>
  </Step>
</Steps>

## Full Code

<CodeGroup>
  ```python Python expandable theme={null}
  import requests
  import json
  from datetime import datetime

  # Configuration
  API_BASE_URL = "https://cloud.onyx.app/api"   # or your own domain
  API_KEY = "YOUR_KEY_HERE"

  headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
  }

  # Projects to create connectors for
  PROJECTS_TO_INDEX = [
    "TECH",
    "SALES",
    "OPS",
  ]

  JIRA_BASE_URL = "https://your-company.atlassian.net"
  connector_ids = []

  # Step 1: Create connectors for each project
  print("Creating connectors...")
  for project_key in PROJECTS_TO_INDEX:
    connector_payload = {
      "name": f"jira-{project_key}",
      "source": "jira",
      "input_type": "poll",
      "access_type": "PUBLIC",
      "connector_specific_config": {
        "jira_base_url": JIRA_BASE_URL,
        "project_key": project_key,
        "comment_email_blacklist": ["legal@company.com"]
      },
      "refresh_freq": 3600,  # Refresh every hour (3600 seconds)
      "prune_freq": 86400,   # Prune every day (86400 seconds)
    }

    response = requests.post(
      f"{API_BASE_URL}/manage/admin/connector",
      headers=headers,
      json=connector_payload
    )

    if response.status_code == 200:
      connector_data = response.json()
      connector_id = connector_data.get('id')
      connector_ids.append(connector_id)
      print(f"Successfully created connector for project {project_key}")
      print(f"Connector ID: {connector_id}")
    else:
      print(f"Failed to create connector for project {project_key}")
      print(f"Status: {response.status_code}")
      print(f"Error: {response.text}")

  # Step 2: Get credentials
  print("\nFetching credentials...")
  response = requests.get(
    f"{API_BASE_URL}/manage/admin/credential",
    headers=headers
  )

  if response.status_code == 200:
    credentials = response.json()
    # Find Jira credential (assumes you have one created)
    jira_credential = next((cred for cred in credentials if cred['source'] == 'jira'), None)

    if jira_credential:
      jira_credential_id = jira_credential['id']
      print(f"Found Jira credential with ID: {jira_credential_id}")
    else:
      print("No Jira credential found. Please create one in the Admin Panel first.")
      exit(1)
  else:
    print(f"Failed to fetch credentials: {response.status_code}")
    print(f"Error: {response.text}")
    exit(1)

  # Step 3: Associate credentials with connectors
  print("\nAssociating credentials with connectors...")
  for connector_id in connector_ids:
    try:
      response = requests.put(
        f"{API_BASE_URL}/manage/admin/connector/{connector_id}/credential/{jira_credential_id}",
        headers=headers,
      )

      if response.status_code == 200:
        print(f"Successfully associated credential with connector {connector_id}")
      else:
        print(f"Failed to associate credential with connector {connector_id}")
        print(f"Status: {response.status_code}. Error: {response.text}")
    except Exception as e:
      print(f"Failed to associate credential with connector {connector_id}: {e}")

  print(f"\nCompleted! Created {len(connector_ids)} connectors with IDs: {connector_ids}")
  ```

  ```bash Shell expandable theme={null}
  #!/bin/bash

  # Configuration
  API_BASE_URL="https://cloud.onyx.app/api"
  API_KEY="YOUR_KEY_HERE"

  # Array of projects to create connectors for
  PROJECTS=("TECH" "SALES" "OPS")
  JIRA_BASE_URL="https://your-company.atlassian.net"

  # Array to store connector IDs
  CONNECTOR_IDS=()

  echo "Creating connectors..."

  # Step 1: Create connectors for each project
  for PROJECT in "${PROJECTS[@]}"; do
    echo "Creating connector for project: $PROJECT"

    RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE_URL}/manage/admin/connector" \
      -H "Authorization: Bearer ${API_KEY}" \
      -H "Content-Type: application/json" \
      -d "{
        \"name\": \"jira-${PROJECT}\",
        \"source\": \"jira\",
        \"input_type\": \"poll\",
        \"access_type\": \"PUBLIC\",
        \"connector_specific_config\": {
          \"jira_base_url\": \"${JIRA_BASE_URL}\",
          \"project_key\": \"${PROJECT}\",
          \"comment_email_blacklist\": [\"legal@company.com\"]
        },
        \"refresh_freq\": 3600,
        \"prune_freq\": 86400
      }"
    )

    HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
    BODY=$(echo "$RESPONSE" | head -n -1)

    if [ "$HTTP_CODE" -eq 200 ]; then
      CONNECTOR_ID=$(echo "$BODY" | jq -r '.id')
      CONNECTOR_IDS+=("$CONNECTOR_ID")
      echo "Successfully created connector for project $PROJECT"
      echo "Connector ID: $CONNECTOR_ID"
    else
      echo "Failed to create connector for project $PROJECT"
      echo "Status: $HTTP_CODE"
      echo "Error: $BODY"
    fi
  done

  # Step 2: Get credentials
  echo -e "\nFetching credentials..."
  CRED_RESPONSE=$(curl -s -w "\n%{http_code}" -X GET "${API_BASE_URL}/manage/admin/credential" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json")

  CRED_HTTP_CODE=$(echo "$CRED_RESPONSE" | tail -n1)
  CRED_BODY=$(echo "$CRED_RESPONSE" | head -n -1)

  if [ "$CRED_HTTP_CODE" -eq 200 ]; then
    JIRA_CREDENTIAL_ID=$(echo "$CRED_BODY" | jq -r '.[] | select(.source == "jira") | .id' | head -n1)

    if [ "$JIRA_CREDENTIAL_ID" != "null" ] && [ -n "$JIRA_CREDENTIAL_ID" ]; then
      echo "Found Jira credential with ID: $JIRA_CREDENTIAL_ID"
    else
      echo "No Jira credential found. Please create one in the Admin Panel first."
      exit 1
    fi
  else
    echo "Failed to fetch credentials: $CRED_HTTP_CODE"
    echo "Error: $CRED_BODY"
    exit 1
  fi

  # Step 3: Associate credentials with connectors
  echo -e "\nAssociating credentials with connectors..."
  for CONNECTOR_ID in "${CONNECTOR_IDS[@]}"; do
    echo "Associating credential with connector: $CONNECTOR_ID"

    ASSOC_RESPONSE=$(curl -s -w "\n%{http_code}" -X PUT "${API_BASE_URL}/manage/admin/connector/${CONNECTOR_ID}/credential/${JIRA_CREDENTIAL_ID}" \
      -H "Authorization: Bearer ${API_KEY}" \
      -H "Content-Type: application/json")

    ASSOC_HTTP_CODE=$(echo "$ASSOC_RESPONSE" | tail -n1)
    ASSOC_BODY=$(echo "$ASSOC_RESPONSE" | head -n -1)

    if [ "$ASSOC_HTTP_CODE" -eq 200 ]; then
      echo "Successfully associated credential with connector $CONNECTOR_ID"
    else
      echo "Failed to associate credential with connector $CONNECTOR_ID"
      echo "Status: $ASSOC_HTTP_CODE"
      echo "Error: $ASSOC_BODY"
    fi
  done

  echo -e "\nCompleted! Created ${#CONNECTOR_IDS[@]} connectors with IDs: ${CONNECTOR_IDS[*]}"
  ```
</CodeGroup>
