Management API
Call Opem from your own server: sync your documentation, read and answer requests, and read the project's usage. Every call carries the project's secret key as Authorization: Bearer sk_…, from the Keys tab of the project's Configuration page, on Professional and Enterprise.
Generated from Opem API 1.0.0 (OpenAPI 3.1.0), the document the API itself publishes at https://support.opem.app/api/openapi.json. The base address is https://support.opem.app.
From Node.js
@opem/node has a typed client for every call below.
import { createManagementClient } from "@opem/node";
const opem = createManagementClient({
secretKey: process.env.OPEM_SECRET_KEY!, // sk_…
});
const { data: open } = await opem.GET(
"/api/v1/manage/requests",
{
params: { query: { status: "open", limit: 25 } },
},
);Management
GET/api/v1/manage/project
The key's own project
Responses
- 200 The project
The body's 20 fields
200 body Field Type Rules id string (uuid) None name string None slug string None environment string one of "production", "staging", "development"
referencePrefix string matches ^[A-Z][A-Z0-9]{1,7}$
allowedOrigins array of string None requireIdentityVerification boolean None identityVerificationRequired boolean None features object None features.ask boolean None features.requests boolean None features.screenshots boolean None features.anonymousVisitors boolean None features.anonymousAsk boolean None features.hybridSearch boolean None monthlyCreditCap integer or null at least 0
realtimeEnabled boolean None lastSeenAt string (date-time) or null None lastSeenOrigin string or null matches ^https?:\/\/[A-Za-z0-9.-]+(?::\d{1,5})?$
createdAt string (date-time) None - 401 unauthenticated
- 403 plan_limit_reached
- 429 rate_limited
GET/api/v1/manage/usage
The key's project's usage for a month
Needs the management API entitlement (Professional and Enterprise).
| Field | In | Type | Rules |
|---|---|---|---|
| periodoptional | query | string | matches ^\d{4}-(?:0[1-9]|1[0-2])$ |
Responses
- 200 The month's usage
The body's 16 fields
200 body Field Type Rules period string matches ^\d{4}-(?:0[1-9]|1[0-2])$
requests integer at least 0
answersPlatform integer at least 0
creditsPlatform integer at least 0
answersOwn integer at least 0
uploadBytes integer at least 0
emails integer at least 0
days array of object None days[].date string (date) None days[].requests integer at least 0
days[].answersPlatform integer at least 0
days[].creditsPlatform integer at least 0
days[].answersOwn integer at least 0
days[].ownTokensIn integer at least 0
days[].ownTokensOut integer at least 0
days[].ownCostMicro integer at least 0
- 401 unauthenticated
- 403 plan_limit_reached
- 422 validation_failed
- 429 rate_limited
Knowledge
GET/api/v1/manage/knowledge/documents
The project's documents
| Field | In | Type | Rules |
|---|---|---|---|
| cursoroptional | query | string | at least 1 character, at most 512 characters |
| limitoptional | query | integer | at least 1, at most 100, default 25 |
Responses
- 200 A page of documents
The body's 16 fields
200 body Field Type Rules items array of object None items[].id string (uuid) None items[].path string at most 300 characters
items[].source string one of "sync", "upload", "authored", "url"
items[].title string None items[].about string or null None items[].bytes integer at least 0
items[].enabled boolean None items[].pathExcluded boolean None items[].sections integer at least 0
items[].access array of string at most 20 items
items[].tags array of string at most 10 items
items[].contentHash string matches ^[a-f0-9]{64}$
items[].syncedAt string (date-time) or null None items[].updatedAt string (date-time) None nextCursor string or null None - 401 unauthenticated
- 403 plan_limit_reached
- 422 validation_failed
- 429 rate_limited
PUT/api/v1/manage/knowledge/documents
Sync documents by path
Up to 100 documents of up to 512 KB each. With prune, synced documents whose path is neither sent nor in keepPaths are deleted; uploaded and authored documents never are.
| Field | Type | Rules |
|---|---|---|
| documents | array of object | at least 1 item, at most 100 items |
| documents[].path | string | at most 300 characters |
| documents[].content | string | None |
| pruneoptional | boolean | default false |
| keepPathsoptional | array of string | at most 5000 items, default [] |
Responses
- 200 What happened to each path
The body's 10 fields
200 body Field Type Rules documents array of object None documents[].path string at most 300 characters
documents[].status string one of "created", "updated", "unchanged", "pruned"
documents[].sections integer at least 0
documents[].issues array of object None documents[].issues[].line integer or null at least 1
documents[].issues[].level string one of "warning", "error", "critical"
documents[].issues[].id string None documents[].issues[].message string None documents[].replacedSourceoptional string one of "upload", "authored"
- 401 unauthenticated
- 403 plan_limit_reached
- 422 validation_failed
- 429 rate_limited
POST/api/v1/manage/knowledge/reindex
Re-parse every document with the current rules
Synchronous: answers once every document of the key's project is re-parsed.
Responses
- 200 The reindex, done
The body's 3 fields
200 body Field Type Rules status string one of "done"
done integer at least 0
total integer at least 0
- 401 unauthenticated
- 403 plan_limit_reached
- 429 rate_limited
Requests
GET/api/v1/manage/requests
The key's project's requests
| Field | In | Type | Rules |
|---|---|---|---|
| cursoroptional | query | string | at least 1 character, at most 512 characters |
| limitoptional | query | integer | at least 1, at most 100, default 25 |
| statusoptional | query | string | one of "open", "sent", "replied", "closed" |
| kindoptional | query | string | matches ^[a-z][a-z0-9-]{0,31}$ |
| blockingoptional | query | string | one of "true", "false" |
| endUserIdoptional | query | string (uuid) | None |
| sinceoptional | query | string (date) | None |
| untiloptional | query | string (date) | None |
Responses
- 200 A page of requests
The body's 19 fields
200 body Field Type Rules items array of object None items[].id string (uuid) None items[].reference string matches ^[A-Z][A-Z0-9]{1,7}-[1-9][0-9]{0,9}$
items[].kind string matches ^[a-z][a-z0-9-]{0,31}$
items[].status string one of "sent", "replied", "closed"
items[].blocking boolean None items[].preview string at most 200 characters
items[].unread boolean None items[].createdAt string (date-time) None items[].lastActivityAt string (date-time) None items[].endUser object None items[].endUser.id string (uuid) None items[].endUser.kind string one of "identified", "anonymous"
items[].endUser.name string or null None items[].endUser.email string or null None items[].endUser.verified boolean None items[].pageUrl string or null None nextCursor string or null None closedNotShown integer or null at least 0
- 401 unauthenticated
- 403 plan_limit_reached
- 422 validation_failed
- 429 rate_limited
PATCH/api/v1/manage/requests/{requestId}
Close or reopen a request
| Field | In | Type | Rules |
|---|---|---|---|
| requestId | path | string (uuid) | None |
| Field | Type | Rules |
|---|---|---|
| status | string | one of "closed", "sent" |
Responses
- 200 The request
The body's 92 fields
200 body Field Type Rules id string (uuid) None reference string matches ^[A-Z][A-Z0-9]{1,7}-[1-9][0-9]{0,9}$
kind string matches ^[a-z][a-z0-9-]{0,31}$
status string one of "sent", "replied", "closed"
blocking boolean None preview string at most 200 characters
unread boolean None createdAt string (date-time) None lastActivityAt string (date-time) None endUser object None endUser.id string (uuid) None endUser.kind string one of "identified", "anonymous"
endUser.name string or null None endUser.email string or null None endUser.verified boolean None endUser.traits object None endUser.otherRequests integer at least 0
endUser.pendingIdentity object or null None endUser.pendingIdentity.emailoptional string (email) at most 320 characters
endUser.pendingIdentity.nameoptional string at least 1 character, at most 200 characters
endUser.pendingIdentity.attemptedAt string (date-time) None pageUrl string or null None message string None pageTitle string or null None errorDigest string or null None context object or null None context.page object None context.page.url string or null at most 2000 characters
context.page.path string or null at most 2000 characters
context.page.title string or null at most 200 characters
context.browser object None context.browser.userAgent string or null at most 300 characters
context.browser.language string or null at most 35 characters
context.browser.timeZone string or null at most 64 characters
context.browser.viewport object or null None context.browser.viewport.width integer at least 0, at most 100000
context.browser.viewport.height integer at least 0, at most 100000
context.browser.screen object or null None context.browser.screen.width integer at least 0, at most 100000
context.browser.screen.height integer at least 0, at most 100000
context.browser.pixelRatio number or null at least 0, at most 10
context.errors array of object at most 10 items
context.errors[].kind string one of "error", "unhandledrejection", "console"
context.errors[].message string at most 500 characters
context.errors[].source string or null at most 2000 characters
context.errors[].line integer or null at least 0
context.errors[].column integer or null at least 0
context.errors[].stack string or null at most 2000 characters
context.errors[].at string (date-time) None context.recentPages array of object at most 10 items
context.recentPages[].path string at most 2000 characters
context.recentPages[].title string or null at most 200 characters
context.recentPages[].at string (date-time) None context.extra object None assistantAnswer object or null None assistantAnswer.answerId string (uuid) None assistantAnswer.question string None assistantAnswer.answer string None assistantAnswer.reads array of object None assistantAnswer.reads[].document string None assistantAnswer.reads[].heading string or null None assistantAnswer.at string (date-time) None attachments array of object None attachments[].fileId string (uuid) None attachments[].name string at most 200 characters
attachments[].contentType string at most 100 characters
attachments[].bytes integer at least 0
statusChangedAt string (date-time) None repliedAt string (date-time) or null None closedAt string (date-time) or null None notification object None notification.status string one of "pending", "sent", "failed", "skipped"
notification.attempts integer at least 0
notification.nextAttemptAt string (date-time) or null None messages array of object None messages[].id string (uuid) None messages[].author string one of "staff", "end_user", "system"
messages[].authorName string or null None messages[].channel string one of "widget", "dashboard", "email", "api"
messages[].text string None messages[].attachments array of object None messages[].attachments[].fileId string (uuid) None messages[].attachments[].name string at most 200 characters
messages[].attachments[].contentType string at most 100 characters
messages[].attachments[].bytes integer at least 0
messages[].createdAt string (date-time) None messages[].direction string one of "inbound", "outbound"
messages[].senderCheck string or null one of "staff", "reporter", "unverified", null
messages[].fromAddress string or null None messages[].subject string or null None messages[].statusEffect string one of "none", "replied", "reopened", "closed"
messages[].relay string one of "pending", "sent", "failed", "not_needed"
- 401 unauthenticated
- 403 plan_limit_reached
- 404 not_found
- 422 validation_failed
- 429 rate_limited
POST/api/v1/manage/requests/{requestId}/messages
Reply to a request from the customer's server
A staff message on channel api, relayed by email as a dashboard reply would be. The author is named by the first word of authorName only.
| Field | In | Type | Rules |
|---|---|---|---|
| requestId | path | string (uuid) | None |
| Field | Type | Rules |
|---|---|---|
| text | string | at least 1 character, at most 5000 characters |
| authorName | string | The staff member the reply is from. Only the first word is stored and shown to the person, as their first name, as for every staff reply; a value holding an email address shows as the project's name instead. at least 1 character, at most 80 characters |
| closeoptional | boolean | default false |
Responses
- 201 The reply
The body's 17 fields
201 body Field Type Rules id string (uuid) None author string one of "staff", "end_user", "system"
authorName string or null None channel string one of "widget", "dashboard", "email", "api"
text string None attachments array of object None attachments[].fileId string (uuid) None attachments[].name string at most 200 characters
attachments[].contentType string at most 100 characters
attachments[].bytes integer at least 0
createdAt string (date-time) None direction string one of "inbound", "outbound"
senderCheck string or null one of "staff", "reporter", "unverified", null
fromAddress string or null None subject string or null None statusEffect string one of "none", "replied", "reopened", "closed"
relay string one of "pending", "sent", "failed", "not_needed"
- 401 unauthenticated
- 403 plan_limit_reached
- 404 not_found
- 422 validation_failed
- 429 rate_limited
Errors
An error is { error: { code, message, requestId, issues? } } with the status its code gives. issues lists where a body, path or query broke the rules. Quote requestId when you write to us. The codes the management API answers with:
| Code | Status | Meaning |
|---|---|---|
| unauthenticated | 401 | No valid credential for this surface |
| plan_limit_reached | 403 | The plan does not allow this, or a limit is reached |
| not_found | 404 | Nothing with that id in the caller's scope |
| validation_failed | 422 | The request does not match the contract |
| rate_limited | 429 | Too many requests; try again shortly |