Overview
We'll walk through our organization endpoint /v2/organization
which allows you to retrieve metadata about your organization including all portfolios managed by the organization.
Authentication
Before making a request, you need to generate an API key and secret. Refer to the api keys section of the overview for details on how to obtain your API credentials.
To authenticate your request for organization routes, you must generate a signature using your API key and secret, and include your organization ID. The request headers should include:
x-definitive-api-key
: Your API keyx-definitive-signature
: A signature generated using your API secretx-definitive-timestamp
: The current timestampx-definitive-organization-id
: Your organization ID (sent as header but NOT included in signature)
:::warning Important
For GET /v2/organization
and most organization-level endpoints, do NOT include the x-definitive-organization-id
header in your request. Instead, provide the organizationId as a query string parameter (e.g., ?organizationId=...
). Only include x-definitive-api-key
, x-definitive-timestamp
, and x-definitive-signature
headers. For portfolio-scoped routes, the portfolioId
in the path is sufficient and the org header is not needed.
:::
Making Your First Request
Here we'll dive into an example request, getting organization details from /v2/organization
. Please note that we've included a helper class AuthHelpers
in the request authorization section to make this easier but we will be walking through the process manually here to help you understand how this works.
Step 1: Define API Key, Secret, Organization ID, and Timestamp
You'll need to access these values in the next few steps.
const apiKey = process.env.API_KEY;
const apiSecret = process.env.API_SECRET;
const organizationId = "00000000-0000-0000-0000-000000000000"; // Your organization ID
const timestamp = Date.now().toString();
Step 2: Prepare the Prehash
For maximum security we require that you use your api secret to sign the request that you're sending and that this signed request is submitted within 2 minutes of creation. To achieve this you must first create a "prehash" of the request. It should look like this:
${method}:${path}?${queryParamsString}:${timestamp}:${sortedHeaders}${bodyString}
;
type PrehashParams = {
method: "GET" | "POST" | "DELETE";
path: string; // eg. /v2/organization
timestamp: string; // stringified timestamp in ms
headers: Record<string, string | number>;
queryParams?: Record<string, string>;
body?: string;
};
// if you're using typescript we recommend copying this method directly
function preparePrehash({
method,
timestamp,
path,
queryParams,
headers,
body,
}: PrehashParams) {
// IMPORTANT: Only include these specific headers in the prehash
// Do NOT include x-definitive-organization-id here
const headersForPrehash: Record<string, string> = {
"x-definitive-api-key": headers["x-definitive-api-key"] as string,
"x-definitive-timestamp": headers["x-definitive-timestamp"] as string,
};
// ensure that the headers are sorted for consistency
const sortedHeaders = Object.entries(headersForPrehash)
.sort(([a], [b]) => a.localeCompare(b))
.map(([key, value]) => `${key}:${JSON.stringify(value)}`)
.join(",");
// stringify the query params eg. 'key=value&key2=value2'
const queryParamsString = new URLSearchParams(queryParams).toString();
const bodyString = body ?? "";
return `${method}:${path}?${queryParamsString}:${timestamp}:${sortedHeaders}${bodyString}`;
}
const timestamp = Date.now().toString();
// generate the message to be signed
const message = preparePrehash({
method: "GET",
path: "/v2/organization",
timestamp,
headers: {
"x-definitive-api-key": apiKey,
"x-definitive-timestamp": timestamp,
// NOTE: Do not include organization ID here
},
queryParams: {},
});
Step 3: Sign the Request
Remove the dpks_
prefix from your api secret and use the resulting string to generate an HMAC of the secret and message.
const secret = apiSecret.replace("dpks_", "");
const signature = crypto
.createHmac("sha256", secret)
.update(message)
.digest("hex");
Step 4: Make the request
This request will return details about your organization and all portfolios within it. Do not include the organization ID header in the request.
// Send request
const result = await fetch("https://ddp.definitive.fi/v2/organization", {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
"x-definitive-api-key": apiKey,
"x-definitive-signature": signature,
"x-definitive-timestamp": timestamp,
},
});
// Parse response
const json = await result.json();
console.log(json);
Using AuthHelpers (Recommended)
For easier development, use the AuthHelpers
class from the request authorization section. Important: Always include the organizationId
parameter for organization routes:
import { AuthHelpers } from "./auth-helpers";
const json = await AuthHelpers.signAndSend({
path: "/v2/organization",
method: "GET",
organizationId: "00000000-0000-0000-0000-000000000000",
});
console.log(json);
Response Format
The response will include organization details and all portfolios:
{
"data": [
{
"portfolioId": "00000000-0000-0000-0000-000000000001",
"portfolioName": "Trading Portfolio",
"createdAt": "2024-08-05T20:48:11.584Z"
}
// ... additional portfolios
],
"pagination": {
"hasMore": false,
"nextCursor": null,
"limit": 10
}
}
Common Authentication Errors
Invalid API Authentication
If you see this error, check:
- Are you including
x-definitive-organization-id
in the prehash? (You shouldn't!) - Are your headers sorted alphabetically in the prehash?
- Are header values JSON.stringified with quotes?
- Is your timestamp within 2 minutes of the current time?
Example of CORRECT prehash headers:
// Only these two headers in prehash:
const headersForPrehash = {
"x-definitive-api-key": apiKey,
"x-definitive-timestamp": timestamp,
};
Example of INCORRECT prehash headers:
// DON'T DO THIS - organization ID should not be in prehash
const headersForPrehash = {
"x-definitive-api-key": apiKey,
"x-definitive-timestamp": timestamp,
"x-definitive-organization-id": organizationId, // WRONG!
};
Error Handling
If the request fails, the API will return an error response with an appropriate status code and message. Common errors include:
401 Unauthorized
: Invalid or missing API key/signature403 Forbidden
: Access denied or invalid organization ID408 Request Timeout
: Timestamp is too old (>2 minutes)500 Internal Server Error
: Unexpected server error
Next Steps
Now that you understand the basics, explore other organization endpoints:
- List Portfolios - View all portfolios in your organization
- Portfolio Management - Get details about specific portfolios
- Portfolio Creation - Create new portfolios
- Trading - Submit trades and get quotes for portfolios
- Order Management - View and manage orders across portfolios
Key Differences from Portfolio API
When using organization routes, remember:
- Always include
organizationId
in yourAuthHelpers.signAndSend
calls - Never include
x-definitive-organization-id
in the signature calculation - Organization routes manage multiple portfolios within an organization
- Portfolio routes work with a single portfolio scope
Summary
To access organization data:
- Generate a prehash message with ONLY
x-definitive-api-key
andx-definitive-timestamp
- Sign the prehash using your API secret
- Send a request with all required headers (do NOT include
x-definitive-organization-id
for GET /v2/organization or portfolio-scoped routes) - Handle the response and possible errors appropriately
For further details, refer to the specific endpoint documentation in this section.