Skip to content

Integration recipe

Verifying schools from Slate

Your extraction pipeline already reads the institution name off a transcript. Nothing in that pipeline asks whether the institution exists. This is how to run that check on every name in your Slate database, in batches, without leaving Slate to do it.

We have not run this against a live Slate instance — VerifyED has no Slate account. The Slate half is derived from Technolutions' published documentation, read on 2026-07-26. The VerifyED half is tested, and the example responses below were captured from production on 2026-07-26.

What Slate can call, and when

Every mechanism Slate documents for talking to an outside API runs on a schedule. There is no documented way to call one from a rule, a form, or a record view — so the recipe below screens in batches. That is a constraint worth knowing before you design around it.

Mechanism Direction Timing
Source Format → Import Automation → Import Remote Server Database → Source Formats → (your format) → Import Automation Slate fetches a file or JSON document from a URL you give it, then runs it through the normal import pipeline. Slate calls us Scheduled. The default is every 24 hours and the documented floor is 60 minutes. Importing Data with Web Services
Query → Schedule Export → Web Service (Remote) Queries / Reports → (your query) → Edit Query → Schedule Export Slate POSTs the rows of a query to a URL, with any headers you configure — including an API key header. Slate sends to us Scheduled, inside two-hour delivery windows in US Eastern time. There are no windows between 5pm and 8pm. Exporting Data with Web Services
Upload Dataset Database → Sources / Upload Dataset A person uploads a CSV by hand. This is how most offices will start, and it is the fastest way to try the recipe. Slate sends to us On demand. Most uploads process within 15 minutes. Upload Dataset

One correction worth making, because it circulates: there is no Slate feature called an “external query”. Searching for the phrase turns up an unrelated Palantir product also named Slate. The two mechanisms above are the real ones.

Read the mill check as a name match

Both of these responses have is_match: true. One is a diploma mill. The other is Harvard, which the matcher scored 0.84 against “Hartford University”. If your Slate rule branches on is_match alone, it flags both — and puts a false accusation in front of a real applicant. Branch on match_type.

Almeda University

is_match: true match_type: "exact" confidence: 1 matched_mill: "Almeda University"

An exact match to a name on the blocklist. Worth stopping on.

Harvard University

is_match: true match_type: "similar" confidence: 0.84 matched_mill: "Hartford University"

A fuzzy name match, and wrong. Branch on match_type, never on is_match alone.

Captured from production on 2026-07-26. The matcher strips words like “university” and “college” before comparing, which is why two unrelated institutions can score highly against each other.

The recipe

Start by uploading one file by hand. An office that has never seen our output should read a file before pointing a scheduled job at it.

  1. Export the names you want checked

    Build a Slate query returning one row per applicant, with the identifier you match on and the school name your extraction pipeline produced. Export it as a CSV with the headers external_id, school_name and country.

    external_id,school_name,country
    APP-99812,Northgate High School,US
    APP-99813,Almeda University,US
  2. Send it to VerifyED

    One request. The response gives you a job id and the two URLs your results will appear at. Up to 1,000 rows per batch.

    curl -X POST https://verifyed.org/api/v1/batch/screen \
      -H "X-API-Key: $VERIFYED_API_KEY" \
      -H "Content-Type: text/csv" \
      --data-binary @applicants.csv
  3. Collect the results

    Poll the job, or configure a webhook and let us tell you. If you take the webhook, verify the X-VerifyEd-Signature header against your signing secret and deduplicate on X-VerifyEd-Delivery-Id — that id is stable across retries, and we may deliver the same event more than once. When the job is done, download the Slate-shaped file.

    curl https://verifyed.org/api/v1/batch/$JOB_ID/results.slate.csv \
      -H "X-API-Key: $VERIFYED_API_KEY" -o verifyed-results.csv
  4. Create the source format in Slate

    Database → Source Formats → New Source Format. Paste the format definition below, upload the file you just downloaded as the sample, and map each column on the Remap screen. Map Unique ID to the field you have marked unique for merging.

  5. Automate it once you trust it

    Two ways round. Point Slate's Import Automation at a URL your office publishes the results file to, or have your own job POST the file to Slate's Upload Dataset endpoint. Either way the schedule is Slate's — the documented floor for a pull is 60 minutes.

The columns

The identifier comes first on the way out, because Slate's own import guidance reserves the first column for the identifier the outside system uses. Everything we assert is prefixed VerifyED so it cannot overwrite a field of yours — the convention other Slate vendors use.

What you send

Column What it is In Slate
external_id Your own identifier for the record this school belongs to. We never interpret it; we hand it back. Export the value you match on — the field you have marked unique for merging. Slate reads only the first 64 characters, so we truncate to 64 and return what it will actually match.
school_name The institution name as it appears on the document. Required. Whichever field your extraction pipeline wrote the school name into.
country Two-letter country code. Optional, and it narrows the search considerably. Optional. Improves matching when you have it.

What comes back

Column What it is In Slate
Unique ID Your external_id, unchanged. Map to the field marked unique for merging. This is what joins our answer to your record.
School 1 Name The name we matched, as the registry holds it — which may differ from what you sent. Slate's documented school column. Maps to School 1 Name.
School 1 CEEB The CEEB code, when the registry has one. Slate's documented school column. Import the file directly — opening it in a spreadsheet first can strip the leading zeros.
VerifyED School ID Our identifier for the matched school, so you can link back to the evidence ledger. A text field.
VerifyED Verification Flag verified, unverified, inconclusive or not_found. not_found means we could not find it — it is a gap in what we hold, not a finding against the school. A prompt field. Map the four values to prompt values so your rules can read them.
VerifyED Match Confidence How close the name match was, from 0 to 1. It measures the name, not the institution. A decimal field.
VerifyED School Type Public, private, and so on, where the registry records it. A text or prompt field.
VerifyED Website The institution's website, where we hold one. A text field.
VerifyED Country The country code you sent, echoed back. A text field.
VerifyED Submitted Name The name you sent us, kept so you can see where it differs from what we matched. A text field. Worth keeping — a large difference here is a reason to look.
VerifyED Checked On The date the batch ran. Every row in one file carries the same date. A date field.
VerifyED Note Why a row could not be screened, or empty. A text field.

The source format

Paste this into the Format Definition tab of a new source format, then upload a results file as the sample so Slate has something to remap against.

<layout b="," h="1" t="&quot;">
  <f s="1"  id="Unique ID" />
  <f s="2"  id="School 1 Name" />
  <f s="3"  id="School 1 CEEB" />
  <f s="4"  id="VerifyED School ID" />
  <f s="5"  id="VerifyED Verification Flag" />
  <f s="6"  id="VerifyED Match Confidence" />
  <f s="7"  id="VerifyED School Type" />
  <f s="8"  id="VerifyED Website" />
  <f s="9"  id="VerifyED Country" />
  <f s="10" id="VerifyED Submitted Name" />
  <f s="11" id="VerifyED Checked On" />
  <f s="12" id="VerifyED Note" />
</layout>

If you would rather Slate read the search endpoint

It parses. Slate needs a named root node and cannot import a document that starts with a bare array; our search response is an object with a named results array, so a layout rooted at /results reads one row per school. Two things to know before you rely on it: the diploma-mill check sits beside the array rather than inside each row, so this layout does not carry it, and Slate has no dynamic array expansion — you enumerate the positions you want.

<layout type="json" node="/results">
  <f s="id"                  id="VerifyED School ID" />
  <f s="name"                id="School 1 Name" />
  <f s="country_code"        id="VerifyED Country" />
  <f s="verification_status" id="VerifyED Verification Flag" />
  <f s="match_quality"       id="VerifyED Match Quality" />
  <f s="match_score"         id="VerifyED Match Confidence" />
  <f s="match_reasons[1]"    id="VerifyED Match Reason 1" />
  <f s="match_reasons[2]"    id="VerifyED Match Reason 2" />
  <f s="match_reasons[3]"    id="VerifyED Match Reason 3" />
</layout>

What we checked

Each of these was checked against a live VerifyED response and against Technolutions' documented parsing rules.

Can Slate parse our search response at all? — Yes
Slate needs a named root node and cannot import a document that starts with a bare array. Our search response is an object with a named results array, so a layout rooted at /results reads one row per school. Technolutions' Format Definition XML page states the rule. We checked a live response: the top level is an object with results, total, cached and diploma_mill_check.
Does the diploma-mill check come through with the rows? — No
diploma_mill_check sits beside the results array, not inside each row. A layout rooted at /results cannot reach it, so a Slate import of the search endpoint gets the matched schools and loses the mill check. Use the batch endpoint instead, which puts a flag on every row. Checked against a live search response. The field is a sibling of results, one level up.
What happens to the nested fields? — With care
match_reasons is an array of strings. Slate has no dynamic array expansion — you enumerate the positions you want with 1-based brackets, so match_reasons[1] is the first reason and anything past what you enumerated is dropped. Technolutions' Format Definition XML page documents bracket indexing. Our live response returned match_reasons as a list.
Can Slate send our API key? — Yes
Both outbound mechanisms support custom HTTP headers, so Slate can send X-API-Key. The export page documents the header syntax directly, including a named API-key header. Technolutions' Importing and Exporting with Web Services pages both document an HTTP Headers field.
Can Slate check a school the moment an application arrives? — No
Every outbound mechanism Technolutions documents runs on a schedule — the fastest documented pull interval is 60 minutes. There is no documented way to call an outside API from a rule or a form. Screen in batches instead; it is what both systems are built for. No such mechanism appears in Technolutions' documentation. We can report that it is undocumented — not that it does not exist.

What we have not tested

  • We have not run this against a live Slate instance. VerifyED has no Slate account, so the source format, the field mapping and the import have not been executed — they are derived from Technolutions' published documentation, read on 2026-07-26.
  • The API side is tested. The endpoints, the CSV columns and the webhook signature on this page are covered by our test suite, and the example responses were captured from production on 2026-07-26.
  • Slate's documentation does not state the HTTP method it uses for an outbound pull, any timeout it applies, or any size cap on the response it will accept. We have not assumed values for these.
  • If you run this and something here is wrong, tell us and we will correct the page rather than leave it standing.

Sources

Every Slate claim on this page comes from one of these, read on 2026-07-26.