/contacts?q=&limit=List contacts in the active site scope.
Scope: contacts.read
Build on OpsIQ with the public API, widget identity, webhooks, connector SDK, action gateway, and OpenAPI contract. These docs are customer-facing and apply to both hosted and self-hosted OpsIQ installs without exposing internal control-plane details.
OpsIQ exposes a stable REST API under /api/v1. Use it when you need to create contacts, open support tickets, read chat history, trigger proactive rules, pull analytics summaries, or manage knowledge-base articles from another system.
The OpenAPI contract is always available at /api/v1/openapi.php. Import it into Postman, Insomnia, Stoplight, or your code generator.
curl /api/v1/openapi.php Use your own OpsIQ domain as the host. The path stays the same across installs.
https://your-opsiq-domain.com/api/v1 Create an API key in OpsIQ, assign only the scopes that integration needs, and send it as a bearer token.
Authorization: Bearer opq_your_key_here curl -H "Authorization: Bearer opq_your_key_here" \
https://your-opsiq-domain.com/api/v1/tickets Keys can be rotated at any time. Store them server-side only. Browser widgets should use the widget identity token flow, not public API keys.
Every API v1 response includes a request_id. Keep it with integration logs so OpsIQ support can trace the exact authenticated request, workspace, action, outcome, and latency without storing the caller's raw IP address.
POST /v1.php
{"action":"meta.me"} meta.me returns the verified key name, scopes, permissions mode, workspace, effective allowed/blocked actions, and recent usage summary for agency and enterprise integrations.
| Scope | Allows | Typical user |
|---|---|---|
contacts.read | List and fetch contacts. | CRM sync, reporting tools. |
contacts.write | Create contacts, update contacts, add tags, add notes. | Forms, stores, enrichment jobs. |
tickets.read | List and fetch tickets. | Dashboards, support QA. |
tickets.write | Create tickets and update ticket status/details. | External forms, platform connectors. |
chats.read | Read chat sessions and transcripts. | BI, compliance export. |
analytics.read | Read summary metrics. | Reporting dashboards. |
proactive.write | Fire a proactive event/rule from another system. | Product events, lifecycle automation. |
kb.write | Create and update knowledge-base articles. | Docs importer, internal tools. |
/contacts?q=&limit=List contacts in the active site scope.
Scope: contacts.read
/contactsCreate a contact.
Scope: contacts.write
curl -X POST https://your-opsiq-domain.com/api/v1/contacts \
-H "Authorization: Bearer opq_your_key_here" \
-H "Content-Type: application/json" \
-d '{"name":"Ada Lovelace","email":"[email protected]","tags":["trial"]}'/contacts/{id}Fetch one contact by id.
Scope: contacts.read
/contacts/{id}Update contact fields, tags, or notes.
Scope: contacts.write
/contacts/{id}/tagsAppend tags to a contact.
Scope: contacts.write
{"tags":["vip","renewal"]}/contacts/{id}/notesAppend a note to a contact timeline.
Scope: contacts.write
{"note":"Customer asked for annual billing."}/tickets?status=&priority=&department_id=&email=&limit=List tickets with filters.
Scope: tickets.read
/ticketsCreate a ticket. New tickets always start as open even if a source platform sends a reply-like status.
Scope: tickets.write
{
"customer_email":"[email protected]",
"customer_name":"Example Customer",
"subject":"Cannot activate account",
"body":"Activation email never arrived.",
"priority":"high",
"department_id":1
}/tickets/{id}Fetch one ticket.
Scope: tickets.read
/tickets/{id}Update status, priority, department, assignment, or subject.
Scope: tickets.write
{"status":"in_progress","priority":"high"}/chats?limit=List chat sessions or client chat threads.
Scope: chats.read
/chats/{id}Fetch one chat session or thread.
Scope: chats.read
Use chat reads for reporting, compliance export, or AI review. For sending live chat messages from a website, use the widget runtime instead of this API.
/analytics/summary?preset=30d&from=&to=Return a summary for the active date range.
Scope: analytics.read
curl -H "Authorization: Bearer opq_your_key_here" \
"https://your-opsiq-domain.com/api/v1/analytics/summary?preset=30d" Analytics responses are site-scoped. Visitor/page metrics stay tied to the domain that collected them; shared site groups do not merge per-domain visitor data.
/proactive/triggerFire a proactive event so OpsIQ rules can react.
Scope: proactive.write
{
"event":"checkout.abandoned",
"email":"[email protected]",
"cart_total":129.50,
"currency":"USD"
}Common events include visitor.high_intent, checkout.abandoned, signup.started, payment.failed, ticket.created, and knowledge.missed_question.
/kb/articlesCreate a knowledge-base article.
Scope: kb.write
{
"title":"How to reset your password",
"body":"Open Account Settings, choose Security, then Reset Password.",
"status":"published"
}/kb/articles/{id}Update a knowledge-base article.
Scope: kb.write
{"status":"published","body":"Updated article body."}The customer AI can use published knowledge-base content when answering visitors, depending on your AI instruction settings.
Install the OpsIQ widget on each website you want to track. Visitor data is collected per domain and stamped to the active site.
<script>
window.OpsIQSettings = {
siteKey: 'site_public_key',
identity: {
email: '[email protected]',
name: 'Example Customer',
external_id: 'cust_123'
}
};
</script>
<script src="https://your-opsiq-domain.com/widget.php" async></script> Use identity when the visitor is logged in. For anonymous visitors, omit identity and OpsIQ will stitch later activity when the visitor identifies themselves.
Webhooks let other tools subscribe to OpsIQ activity. Configure targets in the admin and sign requests with a shared secret.
| Event | When it fires | Useful for |
|---|---|---|
ticket.created | A ticket is opened from chat, email, API, or connector. | External helpdesk mirror. |
ticket.updated | Status, priority, department, assignment, or tags change. | Workflow automation. |
chat.started | A visitor starts a chat. | Sales alerting. |
lead.scored | Lead score crosses a configured threshold. | CRM enrichment. |
order.attributed | A tracked purchase is connected to a visitor/session. | Revenue reporting. |
knowledge.missed_question | The AI could not confidently answer a repeated question. | Content backlog. |
{
"event":"ticket.created",
"id":"evt_123",
"created_at":"2026-05-25T12:00:00Z",
"data":{"ticket_id":42,"subject":"Need help"}
} Connectors are the production path for platform-specific actions. A connector defines metadata, settings, capability flags, and action specs. OpsIQ calls those actions through the gateway so validation, audit hooks, and platform sync stay consistent.
{
"slug":"example_platform",
"name":"Example Platform",
"version":"1.0.0",
"manifest_version":1,
"compatibility":{"opsiq_min":"1.0.0","opsiq_max":"*"},
"capabilities":["native_api","tickets","customers"],
"settings":[{"key":"api_key","type":"password","label":"API key"}]
} {
"id":"ticket.reply",
"label":"Reply to ticket",
"params":{"ticket_id":"string","message":"string"},
"requires_confirmation":true
} Email connectors should expose mailbox/piping settings, not store or currency settings. Commerce connectors should expose order/customer/product actions. Support connectors should expose ticket, comment, assignment, and status actions.
| Status | Meaning | Fix |
|---|---|---|
400 | Invalid request body or parameter. | Check JSON and required fields. |
401 | Missing or invalid bearer token. | Generate or rotate the API key. |
403 | The API key does not have the required scope. | Add the exact scope or use a more limited key per integration. |
404 | Route or resource not found. | Check the endpoint and id. |
422 | Validation failed. | Fix the field named in the error. |
503 | A required service is unavailable. | Check installation health and diagnostics. |
{"success":false,"error":"scope_required:tickets.write","request_id":"req_..."} const res = await fetch('https://your-opsiq-domain.com/api/v1/tickets', {
method: 'POST',
headers: {
Authorization: 'Bearer opq_your_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
customer_email: '[email protected]',
subject: 'Need help',
body: 'The checkout page is failing.'
})
});
const ticket = await res.json(); $ch = curl_init('https://your-opsiq-domain.com/api/v1/contacts');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer opq_your_key_here',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['email' => '[email protected]', 'name' => 'Ada Lovelace']),
]);
$response = json_decode(curl_exec($ch), true); import requests
r = requests.get(
'https://your-opsiq-domain.com/api/v1/analytics/summary',
headers={'Authorization': 'Bearer opq_your_key_here'},
params={'preset': '30d'},
timeout=20,
)
r.raise_for_status()
print(r.json())