aventra.Developers

Your first integration

Turn a lead into a company, a contact and an assigned follow-up task.

This walkthrough uses Node.js 22 or newer and its built-in fetch. It makes real writes to the workspace associated with your API key. Use a test workspace or a company you intend to add.

1. Create a key

Give the key read and write access to companies, contacts and tasks. Save it in AVENTRA_API_KEY, then verify the connection.

export AVENTRA_API_KEY='your-api-key'

2. Add a request helper

Create intake.mjs. This helper checks HTTP status and returns the JSON response. It does not automatically retry writes.

intake.mjs
import { randomUUID } from "node:crypto";

const apiKey = process.env.AVENTRA_API_KEY;
if (!apiKey) throw new Error("Set AVENTRA_API_KEY first.");

async function aventra(path, method = "GET", body) {
  const response = await fetch(`https://api.aventra.no/api/v1${path}`, {
    method,
    headers: {
      Authorization: `Bearer ${apiKey}`,
      ...(body ? { "Content-Type": "application/json" } : {}),
    },
    ...(body ? { body: JSON.stringify(body) } : {}),
    signal: AbortSignal.timeout(30_000),
  });
  const result = await response.json();
  if (!response.ok) {
    throw new Error(`${response.status} ${result.code}: ${result.error}`);
  }
  return result;
}

3. Find the assignee

Use the email of the teammate who should own the follow-up task. This searches only your Aventra workspace.

intake.mjs · continued
const query = new URLSearchParams({ email: "teammate@yourcompany.no" });
const { data: users } = await aventra(`/users?${query}`);
if (users.length !== 1) throw new Error("Choose a workspace member by email.");
const userId = users[0].id;

You can also list workspace users and let someone select a person in your integration.

4. Create or find the company

Add this below the helper. Replace the organisation number with the company you want to add.

intake.mjs · continued
const { data: company, created } = await aventra("/companies", "POST", {
  orgnr: "923609016",
  status: "prospect",
});

console.log(created ? "Company created" : "Company already exists", company.id);

If the company already exists, this operation returns it without changing its status or other fields. A new company gets its name and register details from Aventra. Save the returned id: links, tasks and offers use this CRM UUID, while company URLs use the nine-digit organisation number.

5. Add the contact and email address

intake.mjs · continued
const contactId = randomUUID();
const { data: contact } = await aventra("/contacts", "POST", {
  id: contactId,
  name: "Ola Nordmann",
  notes: "Requested a product demo through our website.",
});

await aventra(`/contacts/${contact.id}/points`, "POST", {
  type: "email",
  value: "ola@example.com",
});

await aventra(`/contacts/${contact.id}/companies`, "POST", {
  company_id: company.id,
  role: "Daglig leder",
});

These are three independent writes. If adding the email address fails, the contact still exists. Keep the completed contact ID and continue from the failed step. Contact names and email addresses are not unique identifiers.

6. Give the lead a next step

intake.mjs · continued
const { data: task } = await aventra("/tasks", "POST", {
  id: randomUUID(),
  title: "Follow up on demo request",
  user_id: userId,
  description: `Contact ${contact.name} at ola@example.com.`,
  related_company_id: company.id,
  due_date: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
});

console.log("Follow-up task created", task.id);

user_id is required. The task is assigned to the workspace member you resolved by email in step 3.

Run the completed file once:

node intake.mjs

Open the company in Aventra and check its contact and task. This example generates new contact and task IDs each run. Running it again creates another contact and task.

Make it reliable

Before putting this in a worker or webhook handler, persist a mapping from your source lead ID to the Aventra contact and task UUIDs before the first request. Reuse those UUIDs when recovering an interrupted job. Store a checkpoint after each successful step. See retry and duplicate handling before adding retries.

For a sales-ready lead, create an offer. For additional conversation context, add a timeline note.

On this page