> ## Documentation Index
> Fetch the complete documentation index at: https://docs.instaview.sk/llms.txt
> Use this file to discover all available pages before exploring further.

# ATS Integration

> Build multi-tenant ATS integrations with InstaView

## 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

<CardGroup cols={2}>
  <Card title="Multi-Company Access" icon="building">
    Manage resources across multiple client companies
  </Card>

  <Card title="Company Creation" icon="plus">
    Create new companies via API
  </Card>

  <Card title="Explicit Company ID" icon="id-card">
    Must specify companyId in requests
  </Card>

  <Card title="Enhanced Permissions" icon="shield-check">
    Special privileges for platform operations
  </Card>
</CardGroup>

## Requesting ATS Access

ATS keys can only be created by InstaView administrators.

<Steps>
  <Step title="Contact Support">
    Email [enterprise@instaview.sk](mailto:enterprise@instaview.sk)
  </Step>

  <Step title="Provide Details">
    * ATS platform name - Expected number of client companies - Integration use
      case - Required scopes
  </Step>

  <Step title="Complete Onboarding">
    Review terms, security requirements, and SLA
  </Step>

  <Step title="Receive ATS Key">
    Secure API key with ATS privileges will be issued
  </Step>
</Steps>

## Using ATS Keys

### Creating Companies

```javascript theme={null}
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:

```javascript theme={null}
// ❌ 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

```javascript theme={null}
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:

```javascript theme={null}
// 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

<Warning>
  **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.
</Warning>

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](/guides/webhooks) for current workarounds and best practices.

## Best Practices

<AccordionGroup>
  <Accordion title="Store Company Mappings" icon="database">
    ```javascript theme={null}
    // 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];
    }
    ```
  </Accordion>

  <Accordion title="Implement Rate Limiting" icon="gauge">
    Spread requests across companies to avoid rate limits:

    ```javascript theme={null}
    async function syncAllClients(clients) {
      for (const client of clients) {
        await syncClient(client);
        await sleep(1000); // Delay between clients
      }
    }
    ```
  </Accordion>

  <Accordion title="Handle Errors Gracefully" icon="triangle-exclamation">
    ```javascript theme={null}
    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;
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Security Considerations

<Warning>
  **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
</Warning>

## Next Steps

<CardGroup cols={2}>
  <Card title="Companies API" icon="building" href="/guides/resources/companies">
    Learn about company management
  </Card>

  <Card title="Webhooks" icon="webhook" href="/guides/webhooks">
    Set up event notifications
  </Card>

  <Card title="Best Practices" icon="star" href="/guides/best-practices">
    Production integration patterns
  </Card>

  <Card title="Support" icon="life-ring" href="mailto:enterprise@instaview.sk">
    Contact enterprise support
  </Card>
</CardGroup>
