A
ApiOne
/Docs

How to build internal enrichment tooling with ApiOne

This guide shows engineering teams how to build internal tools that use ApiOne as a data layer — including a company lookup widget, a Slack bot for on-demand enrichment, and a background enrichment job that runs on new sign-ups.

Use case 1 — Company lookup widget for internal tools

Add a domain lookup widget to your internal admin panel so your team can instantly pull up company data without leaving the tool:

// React component — company lookup widget
import { useState } from 'react';

export function CompanyLookup() {
  const [domain, setDomain] = useState('');
  const [result, setResult] = useState(null);
  const [loading, setLoading] = useState(false);

  async function lookup() {
    setLoading(true);
    try {
      const response = await fetch('/api/enrich/company', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ domain }),
      });
      const data = await response.json();
      setResult(data);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div>
      <input
        value={domain}
        onChange={e => setDomain(e.target.value)}
        placeholder="stripe.com"
        onKeyDown={e => e.key === 'Enter' && lookup()}
      />
      <button onClick={lookup} disabled={loading}>
        {loading ? 'Looking up...' : 'Enrich'}
      </button>
      {result && (
        <div>
          <p><strong>{result.company_name}</strong></p>
          <p>{result.industry} · {result.employee_count} employees</p>
          <p>{result.description}</p>
        </div>
      )}
    </div>
  );
}

// Server-side handler (Express)
app.post('/api/enrich/company', async (req, res) => {
  const { domain } = req.body;
  const response = await fetch('https://apione.store/api/v1/companies/enrich', {
    method: 'POST',
    headers: {
      'X-API-Key': process.env.APIONE_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ domain }),
  });
  const result = await response.json();
  res.json(result.data || {});
});

Use case 2 — Slack bot for on-demand enrichment

import { App } from '@slack/bolt';

const slackApp = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET,
});

// Respond to /enrich command
slackApp.command('/enrich', async ({ command, ack, respond }) => {
  await ack();

  const domain = command.text.trim();
  if (!domain) {
    await respond('Usage: /enrich stripe.com');
    return;
  }

  await respond({ text: `Looking up ${domain}...`, response_type: 'ephemeral' });

  const response = await fetch('https://apione.store/api/v1/companies/enrich', {
    method: 'POST',
    headers: {
      'X-API-Key': process.env.APIONE_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ domain }),
  });
  const result = await response.json();

  if (result.status !== 'success') {
    await respond(`No data found for ${domain}`);
    return;
  }

  const c = result.data;
  await respond({
    blocks: [
      {
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: `*${c.company_name}* (${domain})
${c.industry} · ${c.employee_count} employees · ${c.location}
${c.description}`,
        },
      },
    ],
  });
});

Use case 3 — Background enrichment on sign-up

Automatically enrich every new user's company when they sign up, so your team always has context when reviewing new accounts:

// In your user sign-up handler
async function onUserSignUp(user) {
  // Save the user first — don't block sign-up on enrichment
  await db.users.insert(user);

  // Enrich asynchronously
  enrichUserCompany(user).catch(err => {
    console.error('Background enrichment failed for', user.email, err);
  });
}

async function enrichUserCompany(user) {
  const domain = user.email.split('@')[1];

  // Skip personal email domains
  const personalDomains = ['gmail.com', 'yahoo.com', 'hotmail.com'];
  if (personalDomains.includes(domain)) return;

  // Check if we already have this company enriched
  const existing = await db.companies.findOne({ domain });
  if (existing && existing.enrichedAt > Date.now() - 7 * 24 * 60 * 60 * 1000) {
    // Use cached data (less than 7 days old)
    await db.users.update(user.id, { company_id: existing.id });
    return;
  }

  const response = await fetch('https://apione.store/api/v1/companies/enrich', {
    method: 'POST',
    headers: {
      'X-API-Key': process.env.APIONE_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ domain }),
  });

  const result = await response.json();
  if (result.status !== 'success') return;

  const company = await db.companies.upsert({
    domain,
    ...result.data,
    enrichedAt: Date.now(),
  });

  await db.users.update(user.id, { company_id: company.id });
  console.log(`Enriched company for new user: ${user.email} → ${result.data.company_name}`);
}
Best practice: Always run enrichment asynchronously and never block your primary user flow on an API call. If ApiOne is temporarily unavailable, your sign-up should still complete successfully.

Related