In a world powered by APIs, connectivity is king. Platforms offer dozens, sometimes hundreds, of pre-built integrations to popular services like Salesforce, Stripe, and Slack. But what happens when the service you need to connect to isn't on the list? What about your company's internal inventory system, a niche industry-specific tool, or a brand-new API that hasn't hit the mainstream yet?
Traditionally, you'd be forced back to square one: writing a bespoke integration from scratch. This means wrestling with authentication protocols, managing API keys and refresh tokens, handling rate limits, and writing boilerplate code for every endpoint. It's time-consuming, error-prone, and creates a maintenance burden that scales with every new service you adopt.
But it doesn't have to be this way. With a universal API platform like Integrations.do, you can bring any API—public, private, or unsupported—into a unified, developer-first framework. This guide will walk you through how to build a custom connector, transforming any API into a simple, secure, and callable service.
Before we dive into the "how," let's cover the "why." Creating a custom connector on the .do platform isn't just about connecting to a new system; it's about fundamentally changing how you interact with it.
Let's imagine we need to connect to an internal inventory management system called "LogisticsPrime." It has a private REST API for checking product stock. Here’s how we'd bring it onto the Integrations.do platform.
Every integration starts with some basic metadata. Inside your Integrations.do dashboard, you'll navigate to the custom connector section and define its identity.
This is where the magic begins. Instead of hardcoding credentials in your app, you define the authentication method for LogisticsPrime within our platform's secure vault.
As noted in our FAQs, you have options. For our internal API, it likely uses a simple static API key.
Method: API Key
You'll configure the connector to expect an API key and specify how to send it.
# Conceptual .do Connector Configuration
authentication:
type: apiKey
name: X-API-Key
in: header
When a user on your team connects their account, Integrations.do will prompt them for the key and store it securely. Every subsequent API call made through the connector will automatically include the X-API-Key: <user's_secret_key> header.
What if your API uses OAuth 2.0? Even better. You'd simply provide the Authorization URL, Token URL, Client ID, and Client Secret. Our platform handles the entire multi-step token exchange and refresh lifecycle, completely abstracting it away from your SDK calls.
An API is just a collection of endpoints. To make them useful, we map them to named, callable "Actions." Let's create an action to get a product's stock level.
The LogisticsPrime API has an endpoint: GET /v2/products/{sku}/stock.
We'll define an action called getStockBySKU:
# Conceptual .do Action Definition
actions:
getStockBySKU:
description: "Fetches the current stock for a given product SKU."
method: GET
path: "/products/{{params.sku}}/stock"
parameters:
sku:
type: string
required: true
This simple definition tells the platform that when getStockBySKU is called with a sku parameter, it should make a GET request to the corresponding API endpoint, inserting the sku into the URL.
Raw API responses are often not ideal. They can be nested, have inconsistent naming, or contain more data than you need. The connector can automatically clean this up.
Imagine the LogisticsPrime API returns this object:
{
"status": "success",
"data": {
"productInfo": {
"product_sku": "WDGT-001",
"stock_levels": [
{ "warehouse": "us-east-1", "quantity": 102 },
{ "warehouse": "eu-west-2", "quantity": 55 }
]
}
}
}
We can apply a simple transformation to return a much cleaner object:
// A simple transformation script
return {
sku: data.productInfo.product_sku,
totalStock: data.stock_levels.reduce((sum, loc) => sum + loc.quantity, 0)
};
Now, every time you call this action, you're guaranteed to get a simple, predictable object like { sku: 'WDGT-001', totalStock: 157 }.
After defining the connector, using it in your application is trivially easy. It behaves just like any of our pre-built integrations.
import { integrations } from '@do/sdk';
// Execute our custom action on our custom integration.
// Here, we're fetching stock from our internal LogisticsPrime system.
const inventory = await integrations.logisticsprime.run('getStockBySKU', {
sku: 'WDGT-001'
});
console.log(inventory.sku, inventory.totalStock); // "WDGT-001", 157
// All the complexity of API keys, endpoints, and data
// transformation is handled automatically by the .do platform.
Look at that code. It's clean, readable, and declarative. You're not managing HTTP clients, headers, or JSON parsing. You're just describing what you want to achieve: get the stock for a product. This is the power of Business-as-Code.
While no-code tools like Zapier are great for simple triggers, they lack the programmatic control and flexibility developers need to build robust software. By allowing you to embed any API—even your own—directly into your applications as code, Integrations.do gives you the best of both worlds: the simplicity of a managed platform and the power of on-demand, programmatic execution.
Stop building one-off integration scripts. Start building a unified, scalable, and maintainable system.
Ready to connect your entire tech stack? Sign up for Integrations.do and turn your most complex integration challenges into a few lines of code.