Skip to main content
This guide walks through the complete lifecycle of setting up a customer org — from creation to a fully trained AI agent handling live conversations.

Overview


Step 1: Create the org

Use your Partner API key to create an org for your customer.
curl -X POST https://api.open.cx/partner/v1/orgs \
  -H "Authorization: Bearer YOUR_PARTNER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Tours",
    "external_id": "acme-123",
    "website": "https://acmetours.com",
    "language": "en",
    "ai_instructions": "You are a helpful support assistant for Acme Tours. Help customers with booking questions, cancellations, and tour information. Be friendly and concise."
  }'
Save the id and widget_token from the response — you’ll need both.
The ai_instructions field is the AI profile — the system prompt that defines the agent’s personality, knowledge scope, and behavior. Write it as if you’re briefing a new support agent — who they work for, what they help with, and how they should behave.
See the full request/response schema in the Create Org API Reference.

Step 2: Create an org API key

The Partner API creates the org, but to train the AI and manage the org, you need an org-level API key. Create one with your partner key:
curl -X POST https://api.open.cx/partner/v1/orgs/ORG_ID/api-keys \
  -H "Authorization: Bearer YOUR_PARTNER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Production" }'
Save the api_key from the response — this is the org-level API key you’ll use for all subsequent calls.
The org API key is different from your partner API key. The partner key manages orgs. The org key manages a specific org’s data (training, crawling, contacts, etc). The key is only returned once — store it securely.
All subsequent API calls use the org key:
Authorization: Bearer ORG_API_KEY
See the full request/response schema in the Create Org API Key Reference.

Step 3: Crawl the customer’s website

The fastest way to train the AI is to crawl the customer’s website. The crawler indexes every page into the knowledge base automatically.
curl -X POST https://api.open.cx/crawl \
  -H "Authorization: Bearer ORG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://acmetours.com",
    "page_limit": 500,
    "auto_start_crawl": true,
    "crawl_interval_hours": 168
  }'
You can check crawl progress at any time:
curl https://api.open.cx/crawl/DATASOURCE_ID \
  -H "Authorization: Bearer ORG_API_KEY"
Or sync a single page without a full crawl:
curl -X POST https://api.open.cx/crawl/DATASOURCE_ID/pages/sync \
  -H "Authorization: Bearer ORG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://acmetours.com/faq" }'
See all available parameters and endpoints in the Crawl API Reference.

Step 4: Add custom training

Website content gives the AI factual knowledge. Training scenarios teach it how to behave — tone, policies, edge cases, and workflows.
curl -X POST https://api.open.cx/training \
  -H "Authorization: Bearer ORG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Cancellation policy",
    "content": "Customers can cancel up to 24 hours before their tour for a full refund. Cancellations within 24 hours receive a 50% refund. No-shows are non-refundable."
  }'
Use "type": "BEHAVIORAL" for always-active instructions (tone, guardrails) that apply to every conversation:
curl -X POST https://api.open.cx/training \
  -H "Authorization: Bearer ORG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Brand voice",
    "content": "Always be warm and friendly. Use the customer'\''s first name. Never use corporate jargon.",
    "type": "BEHAVIORAL"
  }'
See all training types, directory management, and search in the Training API Reference.

Step 5: Invite users to the dashboard

Your customers need dashboard access to manage their inbox, handle human handoffs, and review conversations.
curl -X POST https://api.open.cx/partner/v1/orgs/ORG_ID/invitations \
  -H "Authorization: Bearer YOUR_PARTNER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]" }'
The invited user receives an email with a link to create their account. After accepting, they can log into the dashboard and see your partner branding (logo, app name) — not the OpenCX defaults.
Duplicate invitations to the same email are rejected. If a user is already a member of the org, the request returns an error.
See the full request/response schema in the Invite User API Reference.

Step 6: Embed the widget

Use the widget_token from step 1 to embed the chat widget on your customer’s site.
<script
  src="https://cloud.opencopilot.so/widget.js"
  data-token="WIDGET_TOKEN"
></script>
Or with React:
npm install @opencx/widget-react
import { Widget } from '@opencx/widget-react';

function App() {
  return <Widget token="WIDGET_TOKEN" />;
}
If your customers have logged-in users, you can authenticate them so the AI has context:
curl -X POST https://api.open.cx/widget/authenticate-user \
  -H "Authorization: Bearer ORG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "name": "Jane Smith"
  }'
See the full widget setup and authentication options in the Widget docs and Widget Authentication API.

Putting it all together

Here’s a complete example that provisions a customer from scratch:
const PARTNER_KEY = 'YOUR_PARTNER_API_KEY';
const BASE = 'https://api.open.cx';

async function provisionCustomer({ name, externalId, website, instructions }) {
  // 1. Create the org
  const orgRes = await fetch(`${BASE}/partner/v1/orgs`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${PARTNER_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      name,
      external_id: externalId,
      website,
      ai_instructions: instructions,
    }),
  });
  const org = await orgRes.json();
  console.log(`Created org: ${org.id}`);

  // 2. Create an org API key
  const keyRes = await fetch(`${BASE}/partner/v1/orgs/${org.id}/api-keys`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${PARTNER_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ name: 'Production' }),
  });
  const { api_key: orgApiKey } = await keyRes.json();

  // 3. Crawl the website
  await fetch(`${BASE}/crawl`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${orgApiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      url: website,
      page_limit: 500,
      auto_start_crawl: true,
    }),
  });
  console.log(`Started crawling: ${website}`);

  // 4. Add behavioral training
  await fetch(`${BASE}/training`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${orgApiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      title: 'Brand voice',
      content: `You are a support agent for ${name}. Be helpful, friendly, and concise.`,
      type: 'BEHAVIORAL',
    }),
  });
  console.log('Added behavioral training');

  // 5. Invite the customer to the dashboard
  await fetch(`${BASE}/partner/v1/orgs/${org.id}/invitations`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${PARTNER_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ email: `admin@${name.toLowerCase().replace(/\s+/g, '')}.com` }),
  });
  console.log('Invitation sent');

  // 6. Return the widget token for embedding
  return { orgId: org.id, widgetToken: org.widget_token };
}

// Usage
const { widgetToken } = await provisionCustomer({
  name: 'Acme Tours',
  externalId: 'acme-123',
  website: 'https://acmetours.com',
  instructions: 'Help customers with tour bookings and questions.',
});

What’s next

After provisioning, the org is fully operational. The AI will:
  1. Answer questions using crawled website content and training scenarios
  2. Hand off to humans when it can’t resolve an issue (configurable via Handoff settings)
  3. Re-crawl the website on the configured interval to stay up to date
For advanced configuration:

Autopilot Settings

Configure which channels the AI operates on and its behavior mode.

Office Hours

Set business hours — the AI behaves differently outside office hours.

Tags

Auto-tag conversations for categorization and reporting.

Contacts

Manage customer contacts and their metadata.