Airtable Sync
If your student data already lives in Airtable, you can import and re-sync it directly without exporting a CSV. r4ptor connects with a read-only personal access token — it never writes back to Airtable.
The import flow has five steps: Connect → Filters → Map → Preview → Import. On return visits the connection is restored automatically and your filters and column mappings are pre-loaded, so you can go straight to Preview and Import.
Before you start
You need three things from Airtable:
| Item | Where to find it |
|---|---|
| Personal Access Token (PAT) | Airtable → Account → Personal access tokens → Create new token |
| Base ID | Your base URL: https://airtable.com/appXXXXXXXX/... — the appXXXXXXXX part |
| Table name or Table ID | The tab name inside your base (e.g. member) or the tblXXXXXXXX ID from the Airtable API docs |
When creating the PAT, grant it two scopes on the base you want to sync:
data.records:readschema.bases:read
Read-only scopes are sufficient. r4ptor will error if the token is missing either scope.
If your Airtable base contains records for multiple branches, use Filters (Step 2) to restrict the import to your branch. Do not give franchise members access to the full base without filtering.
Step 1 — Connect
- Go to Admin → Import → Airtable tab
- Enter your PAT, Base ID, and Table ID (or table name)
- Click Connect to Airtable
r4ptor calls the Airtable schema API to confirm the connection and fetch every column name and type from your table. Your credentials are saved to App Settings immediately so you won't need to re-enter them next time.
Error messages include the list of available table names. If you get a "Table not found" error, the message will show every table in the base — copy the exact name or ID from there.
Auto-connect on return visits
Once credentials are saved, opening the Airtable tab automatically reconnects in the background. You'll see a brief spinner, then land directly on the Filters step with your saved filters and column map already loaded. If the stored token has expired, the connect form appears with the Base ID and Table pre-filled — enter a new PAT and click Connect.
A "Change" link on the Filters and Map steps lets you switch to a different base or table at any time.
Step 2 — Filters
Filters are applied inside Airtable before any records are fetched. They reduce what r4ptor ever sees — useful for branch isolation or excluding leavers.
Adding a filter
Click + Include or + Exclude, then:
- Pick the column from the dropdown (e.g.
Branch Name,Membership Status) - Wait for r4ptor to load the distinct values from that column — they appear as chips
- Toggle the values you want to include or exclude
You can add multiple filters. All filters are combined with AND — every filter must match for a record to be fetched.
Include vs Exclude
| Type | Behaviour |
|---|---|
| Include | Only fetch records where the column equals one of the selected values |
| Exclude | Fetch all records except those where the column equals one of the selected values |
Example: An EXCLUDE filter on Membership Status = Dropout means dropout members are never fetched, never appear in the preview, and are never imported — not even skipped with an error. They're filtered out at the Airtable API level.
Saving filters
- Save — persists the current filters to App Settings and stays on this step. Use this when you want to add more filters or verify the result before continuing.
- Save & continue — saves and advances to the Map step.
Filters are saved as JSON in App Settings (AIRTABLE_FILTERS) and are automatically reloaded on every subsequent connection.
Step 3 — Map columns
Match your Airtable column names to r4ptor student fields using the dropdowns. Every dropdown shows all columns from your Airtable table. Set unwanted fields to — skip —.
| r4ptor field | Behaviour |
|---|---|
| Student Type * | Required. Matched case-insensitively against your student types. Partial matches work (e.g. Junior matches Juniors). Only used on initial create — never changed on re-sync. |
| Full Name (auto-split) | If your Airtable has a single name column, map it here. r4ptor splits on the first space: Jack Donoghue → first Jack, last Donoghue. |
| First Name | Required if Full Name is not mapped. |
| Last Name | Required if Full Name is not mapped. |
| Used as a fallback matching key on re-sync (see Re-syncing below). | |
| Phone | Mobile number. Stored as-is. |
| Grade | Matched against grade names in your instance for the student's type. If the grade name isn't found, the student is still imported without a grade. |
| Date of birth | Any standard date format Airtable exports. |
What "skip" means on re-sync
Unmapping a field (leaving it as — skip —) means that field is not included in the database update when a matching student record is found. The existing value in r4ptor is left exactly as-is. This lets you sync one field (e.g. Grade / Current Sash) without overwriting others (e.g. Email or Phone) that may have been updated manually in r4ptor.
Student Type is only set when a student is first created. Changing the Student Type mapping or the value in Airtable will not affect existing student records on re-sync — only newly created students pick up the mapped type.
Your column mappings are saved to App Settings (AIRTABLE_FIELD_MAP) when you click Preview Records, and reloaded automatically on the next visit.
Step 4 — Preview
r4ptor fetches the first 20 records (with filters applied) and displays each one with a status:
| Column | Meaning |
|---|---|
| Fetched | Total records returned by Airtable for the preview batch |
| New | Will be created as new students |
| Update | Already exist in r4ptor — will be updated |
| Errors | Missing required fields — will be skipped |
Each row shows:
- + — new student
- ↻ — existing student will be updated
- ! — error — this row will be skipped during import
Fixing Student Type errors inline
If a row shows Student type "X" not recognised, r4ptor couldn't fuzzy-match the Airtable value to any of your student types. You can fix it directly in the preview table:
- Find the row with the
!error - Use the Student Type dropdown that appears in that row
- Pick the correct type
These manual overrides are passed to the import as typeOverrides. A student fixed this way is imported with the type you selected, regardless of what Airtable says. The override is not saved permanently — you'd need to re-apply it if you run the preview again.
If your Airtable has consistent type values that just don't match the name format, the better fix is to rename your student types in r4ptor to match Airtable (or vice versa) so the fuzzy match works automatically.
Step 5 — Import
Click Import All from Airtable to process every record in the table (not just the preview set). r4ptor paginates through the full table automatically, fetching 100 records per page.
The same filters you configured in Step 2 are applied to every page of records — you never import more than what the filters allow.
When complete, you'll see:
| Stat | Meaning |
|---|---|
| Created | New student profiles created |
| Updated | Existing students refreshed with new field values |
| Skipped | Records missing required fields (name or unresolvable student type) |
| Errors | Database errors on individual records (check logs) |
Re-syncing
After the first import, r4ptor stores the Airtable record ID (airtableRecordId) on each student profile. On subsequent syncs, matching works in this order:
- Airtable record ID — matched first. Renaming a student in Airtable won't create a duplicate.
- Email — fallback if no stored record ID matches (e.g. a student added in Airtable after the last sync). Only attempted if the Email field is mapped.
- Create new — if neither matches, a new student profile is created.
There's no minimum sync interval — it's safe to run as often as needed.
Troubleshooting
| Error | Fix |
|---|---|
Airtable 401 / Invalid PAT | Token has expired or been revoked. Generate a new one in Airtable → Account → Personal access tokens. |
Table "X" not found. Available: … | The error lists every table in the base. Copy the exact name or tblXXXXXXXX ID from the list. |
No fields returned | PAT is missing schema.bases:read scope. Delete and re-create the token with both required scopes. |
Student type "X" not recognised | The Airtable value doesn't match any student type name. Either fix inline in Preview, or rename the student type in r4ptor → Admin → Settings → Student Types to match. |
Name missing | The Full Name column is blank for this record, or First/Last Name columns aren't mapped. Check the mapping and confirm the Airtable data is populated. |
| Duplicates after re-sync | Duplicates can occur if a student was previously imported via CSV without an Airtable record ID stored, and their email address differs between the two sources. Merge the duplicate profiles manually in People. |