Everything you need to run customer support from inside your own product with Dbrij Resolve: desks, tickets, replies, confirmations, scopes, metering and webhook events.
Run customer support from inside your own product on Dbrij Resolve. Your app acts with its owner's standing: it sees the desks of the companies they belong to, opens tickets on a customer's behalf, reads the honest state (status, public timeline, the desk score) and relays replies and confirmations. Set the desk up in Resolve first; everything here rides on it.
Authenticate with an API key carrying the support:read / support:write scopes. Each ticket you open is metered per app per month as support_tickets against your plan: the free tier has a hard monthly allotment while paid plans bill overage instead, and every request counts toward your plan's per minute rate ceiling (429).
/support/deskssupport:readList desks
Every Resolve desk your app can act on, across the companies its owner belongs to.
curl -X GET https://api.dbrij.com/api/support/desks \
-H "Authorization: Bearer $DBRIJ_API_KEY"{
"success": true,
"data": [ { "id": "d4e5…", "name": "Acme Support", "code": "ACME", "organizationId": "o3b4…" } ]
}/support/desks/:deskId/scoresupport:readDesk score
The desk’s honest numbers, machine readable: promises kept, confirmed closes, first reply speed, reopens and CSAT.
PATH / BODY PARAMETERS
| deskId* | string (path) | The desk id. |
curl -X GET https://api.dbrij.com/api/support/desks/:deskId/score \
-H "Authorization: Bearer $DBRIJ_API_KEY"/support/desks/:deskId/ticketssupport:readList tickets
Tickets on a desk, newest activity first (max 100). Filter to one customer with the email query.
PATH / BODY PARAMETERS
| deskId* | string (path) | The desk id. |
QUERY PARAMETERS
| string | Only tickets belonging to this customer email. |
curl -X GET https://api.dbrij.com/api/support/desks/:deskId/tickets \
-H "Authorization: Bearer $DBRIJ_API_KEY"{
"success": true,
"data": [ { "id": "t9d1…", "reference": "ACME-42", "subject": "Payment failed on checkout", "status": "open", "awaitingReply": true, … } ]
}/support/desks/:deskId/ticketssupport:writeOpen a ticket
Open a ticket on a customer’s behalf from inside your own product. The customer is upserted by email on the desk. Metered as support_tickets, one per ticket created.
PATH / BODY PARAMETERS
| deskId* | string (path) | The desk id. |
| email* | string | The customer’s email. |
| name | string | The customer’s name. |
| externalId | string | Your own user id for the customer, for joining on your side. |
| subject* | string | What the ticket is about. |
| body* | string | The customer’s first message. |
curl -X POST https://api.dbrij.com/api/support/desks/:deskId/tickets \
-H "Authorization: Bearer $DBRIJ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"name": "Jane",
"externalId": "user_42",
"subject": "Payment failed on checkout",
"body": "My card was charged but the order shows unpaid."
}'{
"email": "jane@example.com",
"name": "Jane",
"externalId": "user_42",
"subject": "Payment failed on checkout",
"body": "My card was charged but the order shows unpaid."
}{
"success": true,
"data": {
"id": "t9d1…",
"reference": "ACME-42",
"subject": "Payment failed on checkout",
"status": "open",
"statusLabel": "Open",
"awaitingReply": true,
"firstReplyDueAt": "2026-07-01T10:00:00.000Z",
"resolvedAt": null,
"customerConfirmedAt": null,
"createdAt": "2026-07-01T09:00:00.000Z",
"lastMessageAt": "2026-07-01T09:00:00.000Z"
}
}/support/tickets/:ticketIdsupport:readGet a ticket
One ticket with its public conversation and timeline. Internal team notes never appear here.
PATH / BODY PARAMETERS
| ticketId* | string (path) | The ticket id. |
curl -X GET https://api.dbrij.com/api/support/tickets/:ticketId \
-H "Authorization: Bearer $DBRIJ_API_KEY"{
"success": true,
"data": {
"id": "t9d1…",
"reference": "ACME-42",
"status": "resolved",
"messages": [ { "id": "m1…", "from": "customer", "body": "…", "createdAt": "…" }, { "id": "m2…", "from": "team", "body": "…", "createdAt": "…" } ],
"timeline": [ { "kind": "opened", "summary": "Ticket opened", "createdAt": "…" } ],
…
}
}/support/tickets/:ticketId/messagessupport:writeRelay a customer reply
A reply the customer typed inside your product, landed on the ticket exactly like a portal reply.
PATH / BODY PARAMETERS
| ticketId* | string (path) | The ticket id. |
| body* | string | The customer’s message. |
curl -X POST https://api.dbrij.com/api/support/tickets/:ticketId/messages \
-H "Authorization: Bearer $DBRIJ_API_KEY"{
"success": true,
"data": { "ok": true }
}/support/tickets/:ticketId/filessupport:writeSend the customer’s files
Screenshots or documents from the customer, sent as multipart form data. Stored by Dbrij and posted as one message, with or without words. Up to 5 files of 25 MB each: images, PDFs, Office documents and text files.
PATH / BODY PARAMETERS
| ticketId* | string (path) | The ticket id. |
| files* | file (multipart) | One to five files, each under the field name files. |
| body | string (multipart) | Words to go with them. |
curl -X POST https://api.dbrij.com/api/support/tickets/:ticketId/files \
-H "Authorization: Bearer $DBRIJ_API_KEY"{
"success": true,
"data": { "ok": true, "attachments": [ { "id": "…", "name": "screenshot.png", "url": "https://…", "mimeType": "image/png", "sizeBytes": 48211 } ] }
}/support/tickets/:ticketId/confirmsupport:writeConfirm the fix
The customer confirmed the fix inside your product: the honest close. Only a ticket in status resolved can be confirmed; it moves to closed and any linked task closes with it.
PATH / BODY PARAMETERS
| ticketId* | string (path) | The ticket id. |
curl -X POST https://api.dbrij.com/api/support/tickets/:ticketId/confirm \
-H "Authorization: Bearer $DBRIJ_API_KEY"{
"success": true,
"data": { "id": "t9d1…", "status": "closed", "customerConfirmedAt": "2026-07-02T08:30:00.000Z", … }
}Tickets opened through the API carry your app id, so support.ticket.created, support.ticket.replied, support.ticket.resolved, support.ticket.confirmed and support.ticket.closed fire to your webhook URL in the same signed envelope as every other event. Verify X-Dbrij-Signature exactly as described on the Webhooks tab.
A ticket never closes because the team says so. The team marks it resolved; it only becomes closed when the customer confirms, either in the portal or through POST /support/tickets/:id/confirm from your product. Build your UI around that: show the fix, ask the customer, send the confirmation.
Every SDK and package for Resolve, with what it does, how to install it and the smallest working use. The whole catalogue, for every product, is on the apps page.
A support bubble for any website: one script tag opens your Resolve desk in a panel on the page.
Script for your site · JavaScript · Served by Dbrij · Runs on Browsers
<script src="https://resolve.dbrij.com/resolve-widget.js" data-desk="rk_..." defer></script><script src="https://resolve.dbrij.com/resolve-widget.js" data-desk="rk_..." data-email="ada@example.com" data-user-hash="HMAC_FROM_YOUR_SERVER" defer></script>Resolve inside Capacitor, Ionic, Cordova and web apps: the support screen, signed sign in and the unread badge.
SDK · TypeScript · npm · Runs on Capacitor, Ionic, Cordova, Browsers, Any runtime with fetch
npm install @dbrij/resolveimport { openResolve } from '@dbrij/resolve';const screen = openResolve({ desk: 'rk_...', identity: { email, name, externalId, userHash }, // userHash from your server onClose: () => {},});// screen.close() from your own back buttonResolve for React Native and Expo: your support desk as a screen in your app, with signed sign in, screenshots on tickets and the unread badge.
SDK · TypeScript · npm · Runs on React Native 0.71+, Expo, React 18+
npm install @dbrij/resolve-react-native react-native-webviewimport AsyncStorage from '@react-native-async-storage/async-storage';import { ResolveSupport } from '@dbrij/resolve-react-native';export function HelpScreen({ navigation }) { return ( <ResolveSupport desk="rk_..." identity={{ email: user.email, name: user.name, externalId: user.id, userHash: user.resolveHash }} storage={AsyncStorage} onClose={() => navigation.goBack()} /> );}Resolve for iOS in Swift: your support desk as a screen in SwiftUI or UIKit, with signed sign in, screenshots on tickets and the unread badge.
SDK · Swift · Swift Package Manager · Runs on iOS 15+, Swift 5.9+
.package(url: "https://github.com/DbrijHQ/resolve-ios", from: "0.1.0")import DbrijResolvelet me = ResolveIdentity(email: user.email, externalId: user.id, userHash: user.resolveHash).sheet(isPresented: $showHelp) { ResolveSupportView(desk: "rk_...", identity: me) { showHelp = false }}Resolve for Android in Kotlin: your support desk as a screen in your app, with signed sign in, screenshots on tickets and the unread badge.
SDK · Kotlin · JitPack · Runs on Android 6+ (API 23)
// settings.gradle.kts, under dependencyResolutionManagement.repositoriesmaven { url = uri("https://jitpack.io") }// app/build.gradle.ktsimplementation("com.github.DbrijHQ:resolve-android:0.1.0")import com.dbrij.resolve.ResolveIdentityimport com.dbrij.resolve.ResolveSupportResolveSupport.open( context, desk = "rk_...", identity = ResolveIdentity(email = user.email, externalId = user.id, userHash = user.resolveHash),)Resolve for Flutter: your support desk as a screen in your app, with signed sign in, screenshots on tickets and the unread badge.
SDK · Dart · pub.dev · Runs on Flutter 3.16+, iOS, Android
flutter pub add dbrij_resolvefinal resolve = ResolveClient(desk: 'rk_...', storage: MyStorage());Navigator.of(context).push(MaterialPageRoute( builder: (ctx) => Scaffold( body: SafeArea( child: ResolveSupport( desk: 'rk_...', client: resolve, identity: ResolveIdentity(email: user.email, externalId: user.id, userHash: user.resolveHash), onClose: () => Navigator.of(ctx).pop(), ), ), ),));Dbrij is Nigeria’s company operating system: the first Nigerian built platform to put team chat, video meetings, email, HR, tax compliant payroll, customer support, marketing, analytics and cloud hosting in one product on one subscription.