Skip to main content

Single Tool Mode

Direct customers to specific connectors with customized activation flows that align with your application workflow.

Services API

The first step is to retrieve a list of tools that are pre-configured via Unizo Console. This is accomplished by making an API call to /services.

Retrieve List of All Services

Endpoint: GET https://api.unizo.ai/api/v1/services

Retrieves list of all services.

Required Headers

HeaderTypeRequiredDescription
apikeyStringYesAPI key for authenticating requests to Unizo. Found in the Unizo Console.

Sample Request

// Fetch all services configured in your Unizo Console.
// Each service represents a connector (e.g., GitHub, Jira, Google Drive)
// that your customers can integrate with.
const response = await fetch('https://api.unizo.ai/api/v1/services', {
headers: {
'apikey': process.env.UNIZO_API_KEY // Your Unizo API key from the Console
}
});

const services = await response.json();

// Each service has an `id` that you'll use later as the `serviceId`
// to launch the Connect UI for that specific tool.
// Typically, you'd render these as cards or a list in your UI,
// storing the `id` on each button/card for the click handler.
services.forEach(service => {
console.log(`${service.name} (${service.type}) — ID: ${service.id}`);
});

Sample Response

[
{
"type": "SCM", // Category: Source Code Management
"id": "6331064d-914c-4a79-a0a7-8bd3896d06e2", // Use this as serviceId in Connect UI
"name": "GitHub Enterprise", // Display name for your UI
"state": "ACTIVE", // Only show ACTIVE services to users
"serviceProfile": {
"id": "uuid",
"name": "GitHub Enterprise",
"image": { // Connector logos for your UI
"original": "https://...",
"small": "https://...", // 64px — good for list views
"medium": "https://...", // 128px — good for card views
"large": "https://..." // 256px — good for detail views
}
}
}
]

Service Keys API

When a user clicks on one of the tools listed, make an API call to /serviceKeys to start a session. The service key is a short-lived token that authorizes the Connect UI to create an integration on behalf of your customer.

Endpoint: POST https://api.unizo.ai/api/v1/serviceKeys

Required Headers

HeaderTypeRequiredDescription
apikeyStringYesAPI key for authenticating requests to Unizo.

Sample Request

// When a user clicks "Connect GitHub" in your app, create a service key.
// This generates a unique, time-limited URL for the Connect UI iframe.
//
// IMPORTANT:
// - Call this from your backend, not the browser (protects your API key)
// - Each service key is single-use and expires (see expirationDateTime in response)
// - The subOrganization identifies YOUR customer — use a stable external ID
// so Unizo can associate integrations with the right customer
const response = await fetch('https://api.unizo.ai/api/v1/serviceKeys', {
method: 'POST',
headers: {
'apikey': process.env.UNIZO_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
// Descriptive name — helps you identify this key in logs and the Console
name: "github-integration-for-acme",

// Your customer's identity. Unizo uses this to group all integrations
// for a single customer together — critical for multi-tenant apps.
subOrganization: {
name: "Acme Inc", // Customer display name
externalKey: "acme-id-41c6-9404-18b9cfb3ed3b" // Your internal customer ID
},

// Which category of integrations to show.
// This scopes the Connect UI to only show connectors in this category.
integration: {
target: {
type: "Category",
categorySelectors: [
{ type: "SCM" } // Options: SCM, TICKETING, COMMS, VMS, EDR,
// IDENTITY, INCIDENT, PCR, INFRA, KMS,
// MONITORING, STORAGE
]
}
}
})
});

const serviceKey = await response.json();

// The formDescriptorUrl is the iframe src — pass it to your frontend
// along with the serviceId of the specific tool the user clicked
console.log('Iframe URL:', serviceKey.formDescriptorUrl);

Sample Response

{
"type": "INTEGRATION_TOKEN",
"id": "197fca710090ef92f23c2d948f1",
"state": "ACTIVE",
"name": "github-integration-for-acme",
"displayId": "197fca710090ef92f23c2d948f1",
"formDescriptorUrl": "https://dock.unizo.ai/links/197fca710090ef92f23c2d948f1", // Use as iframe src
"frontendUrl": "https://dock.unizo.ai",
"expirationDateTime": "1752292296", // Unix timestamp — key expires after this
"subOrganization": {
"externalKey": "acme-id-41c6-9404-18b9cfb3ed3b",
"name": "Acme Inc"
},
"integration": {
"type": "GENERIC",
"target": {
"type": "Category",
"categorySelectors": [
{ "type": "SCM" }
]
}
}
}

Embedding the Connect UI in Your Frontend

Set the iframe src to the formDescriptorUrl from the Service Keys API response, with the serviceId query parameter appended to identify the specific tool.

Complete Example

Step 1: Add the iframe

In production, replace {serviceKeyId} with the formDescriptorUrl ID from the Service Keys API response, and {serviceId} with the service ID from the Services API.

Iframe Embed
<!-- Connect UI iframe — renders the connector modal for a single service -->
<div id="connect-container"
style="display: flex; justify-content: center; padding: 20px;">
<iframe
id="unizo-connect"
src="https://dock.unizo.ai/links/{serviceKeyId}?serviceId={serviceId}"
width="480"
height="700"
frameborder="0"
style="border: none; border-radius: 12px;
box-shadow: 0 4px 24px rgba(0,0,0,0.12);">
</iframe>
</div>

Step 2: Listen for events

Add this script to capture the integration ID when created and clean up the iframe when the user is done.

Event Handling
// Store the integration ID when created — you'll need this to make
// API calls (e.g., list repositories, create tickets) on behalf of
// your customer's connected account.
let newIntegrationId = null;

window.addEventListener('message', function (event) {
// SECURITY: Always validate the origin in production.
// This prevents other iframes or windows from spoofing events.
if (event.origin !== 'https://dock.unizo.ai') return;

const { type, body } = event.data;

// STEP 1: Capture the integration ID
// This fires as soon as the user completes authorization.
// Save this ID to your database — you'll pass it as the
// integrationId header on all Unizo unified API calls.
if (type === 'integration.created') {
newIntegrationId = body.integration.id;

// Example: POST to your backend to store the integration
fetch('/api/integrations', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
integrationId: newIntegrationId,
customerId: 'acme-id-41c6-9404-18b9cfb3ed3b' // Your customer ID
})
});
}

// STEP 2: Handle the modal close
// This fires AFTER integration.created (if successful).
// Use this to clean up the iframe and update your UI.
if (type === 'connect.close') {
const container = document.getElementById('connect-container');

if (body.reason === 'completed') {
// User finished successfully — show confirmation
container.innerHTML = '<p>Integration connected!</p>';

// Optional: redirect to your integrations dashboard
// window.location.href = '/dashboard/integrations';
} else {
// User cancelled (reason: 'user_dismissed')
// Hide the iframe — they can try again later
container.style.display = 'none';
}
}
});

Query Parameters

ParameterTypeRequiredDescription
serviceIdUUIDYesThe ID of the service to connect. When provided, the iframe renders only the connector for this service against a clean background — no category headers, service cards, or page titles are visible. When omitted, the full integration catalog is shown. Obtained from the Services API.

Clean Background

When you pass a serviceId in the iframe URL, the Connect UI skips the full catalog view and opens the connector modal directly against a clean, solid background. Only the connector for the specified service is shown — this creates a focused, distraction-free experience that feels native to your application.

Event Reference

EventWhenKey Fields
integration.createdIntegration is successfully created during the auth flowbody.integration.id — save this to make API calls on behalf of the user
connect.closeUser closes the connector modalbody.reason — determines your next action

Close Reasons

ReasonWhenRecommended Action
completedUser clicked "Done" after successfully creating the integrationShow success confirmation, redirect to dashboard
user_dismissedUser clicked X, back button, or cancelled without completingHide the iframe, optionally show a "try again" prompt
Event Order

The integration.created event fires when the integration is created (during the auth flow). The connect.close event fires afterward when the user closes the modal. Listen for both to capture the integration data and clean up the iframe.

ViewportWidthHeightNotes
Desktop480px700pxCentered modal card
Tablet440px650pxCentered modal card
Mobile100%100%Full screen

Advanced Customization

You can combine Single Tool Mode with flow configuration to further customize the pre-authorization experience — skip steps, override text, or customize buttons. See Flow Configuration for details.


For additional support, contact our team at [email protected].