Skip to main content

Overview

ATS (Applicant Tracking System) integration keys allow platforms custom ATS solutions to manage multiple companies through a single API key. This is ideal for multi-tenant applications.

ATS Key Characteristics

Multi-Company Access

Manage resources across multiple client companies

Company Creation

Create new companies via API

Explicit Company ID

Must specify companyId in requests

Enhanced Permissions

Special privileges for platform operations

Requesting ATS Access

ATS keys can only be created by InstaView administrators.
1

Contact Support

2

Provide Details

  • ATS platform name - Expected number of client companies - Integration use case - Required scopes
3

Complete Onboarding

Review terms, security requirements, and SLA
4

Receive ATS Key

Secure API key with ATS privileges will be issued

Using ATS Keys

Creating Companies

async function createClientCompany(companyData) {
  const response = await fetch(
    "https://api.instaview.sk/companies",
    {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${atsApiKey}`, // ATS key required
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        name: companyData.name,
        website: companyData.website,
        industry: companyData.industry,
      }),
    }
  );

  const { data } = await response.json();
  return data.id; // Save this companyId
}

Accessing Company Resources

All resource requests must include companyId query parameter:
// ❌ Wrong: Missing companyId
GET /jobs
Authorization: Bearer sk_live_ats_key

// ✅ Correct: Includes companyId
GET /jobs?companyId=company-uuid
Authorization: Bearer sk_live_ats_key

Example Integration

class ATSIntegration {
  constructor(atsApiKey) {
    this.apiKey = atsApiKey;
    this.baseURL = "https://api.instaview.sk/v1";
  }

  async onboardClient(atsClient) {
    // 1. Create company in InstaView
    const company = await this.createCompany({
      name: atsClient.name,
      website: atsClient.website,
    });

    // 2. Sync jobs
    for (const atsJob of atsClient.jobs) {
      await this.createJob(company.id, atsJob);
    }

    // 3. Sync candidates
    for (const atsCandidate of atsClient.candidates) {
      await this.createCandidate(company.id, atsCandidate);
    }

    return company.id;
  }

  async createJob(companyId, jobData) {
    return await fetch(`${this.baseURL}/jobs?companyId=${companyId}`, {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${this.apiKey}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(jobData),
    });
  }

  async syncCandidates(companyId, candidates) {
    const results = [];

    for (const candidate of candidates) {
      const result = await this.createCandidate(companyId, candidate);
      results.push(result);
      await this.sleep(200); // Rate limiting
    }

    return results;
  }
}

Data Isolation

Each company’s data is strictly isolated:
// Company A's data
GET /jobs?companyId=company-a-uuid
// Returns: Company A's jobs only

// Company B's data
GET /jobs?companyId=company-b-uuid
// Returns: Company B's jobs only

// ❌ Attempting to access unmanaged company
GET /jobs?companyId=unauthorized-company-uuid
// Returns: 403 Forbidden

Webhook Configuration

Webhooks are not yet implemented. The webhook configuration endpoints described below are planned for future implementation. Currently, you need to poll the API to check for updates.
Webhook configuration will be available in a future release. When implemented, you’ll be able to set up webhooks per company to receive real-time notifications for events like interview completion and candidate updates. For now, use polling to check for updates. See the Webhooks Guide for current workarounds and best practices.

Best Practices

// Map ATS client IDs to InstaView company IDs
const companyMapping = {
  'ats-client-123': 'instaview-company-uuid-1',
  'ats-client-456': 'instaview-company-uuid-2'
};

function getInstaViewCompanyId(atsClientId) {
  return companyMapping[atsClientId];
}
Spread requests across companies to avoid rate limits:
async function syncAllClients(clients) {
  for (const client of clients) {
    await syncClient(client);
    await sleep(1000); // Delay between clients
  }
}
async function safeCreateResource(companyId, resourceData) {
  try {
    return await createResource(companyId, resourceData);
  } catch (error) {
    if (error.code === 'RESOURCE_ACCESS_DENIED') {
      console.error(`No access to company ${companyId}`);
      // Remove from managed companies
    }
    throw error;
  }
}

Security Considerations

ATS keys have elevated privileges. Implement additional security: - Never expose ATS keys in client-side code - Use separate keys for production and testing - Rotate keys every 90 days - Monitor for unusual access patterns - Implement IP allowlists

Next Steps