For Developers

Getting Started

This guide gets you from zero to listing institutions with the Public Data API as quickly as possible.

1. Create a Publishable Key

  1. Create or open a team in the Edlink Dashboard.
  2. Open Getting Started and complete the Public Data API steps.
  3. Create an application and copy its publishable key (pk_...).

You will send this key as a bearer token on every Public Data API request.

Use a publishable key (pk_...), not a secret key. Publishable keys are safe for client-side use with the Public Data API and widgets.

2. Make Your First Request

Search for institutions by name (or city, state, or postal code):

const publishable_key = 'pk_...';

const response = await fetch('https://ed.link/api/v2/institutions?$search=Lincoln&$first=25', {
    headers: {
        Authorization: `Bearer ${publishable_key}`
    }
});

const { $data } = await response.json();
console.log($data);

Each item in $data is an Institution with a stable id you can store in your own system.

Want companies instead? Use the same pattern against /api/v2/companies.

3. Filter and Page Through Results

For larger pulls, use $filter, $expand, and cursor pagination via $next. This example lists California districts and expands their addresses:

const publishable_key = 'pk_...';

async function* listInstitutions(
    filter?: Record<string, Array<{ operator: string; value: string }>> | null,
    expand?: string[] | null,
    limit: number = 1000
) {
    const url = new URL('/api/v2/institutions', 'https://ed.link');
    url.searchParams.set('$first', limit.toString());

    if (expand) {
        url.searchParams.set('$expand', expand.join(','));
    }

    if (filter) {
        url.searchParams.set('$filter', JSON.stringify(filter));
    }

    let next: string | null = url.toString();

    do {
        const res = await fetch(next, {
            method: 'GET',
            headers: {
                Authorization: `Bearer ${publishable_key}`
            }
        });

        if (!res.ok) {
            throw new Error(`Response status: ${res.status}`);
        }

        const { $data, $next } = await res.json();

        for (const item of $data) {
            yield item;
        }

        next = $next ?? null;
    } while (next !== null);
}

const filter = {
    'addresses.state': [{ operator: 'equals', value: 'California' }],
    'addresses.country': [{ operator: 'equals', value: 'United States' }],
    type: [{ operator: 'equals', value: 'district' }]
};

for await (const institution of listInstitutions(filter, ['addresses'])) {
    console.log(institution.id, institution.name);
}

Tips:

  • Prefer $search when a user is typing a school name in a UI.
  • Prefer $filter + $next when you need a precise, pageable dataset.
  • Do not combine $search with cursor pagination ($after / $before); use $offset instead.

4. Fetch a Single Institution

Once you have an ID, load the full record (including parent and children):

const institution_id = '00000000-0000-0000-0000-000000000000';

const response = await fetch(`https://ed.link/api/v2/institutions/${institution_id}`, {
    headers: {
        Authorization: `Bearer ${publishable_key}`
    }
});

const { $data } = await response.json();
console.log($data.institution, $data.parent, $data.children);

Prefer a UI Instead?

Skip the hard part and drop in a pre-built widget:

Next Steps

Here are some links to the API/Model reference if you need more info.

Institutions:

Companies: