AutoviaTest

v1Updated 24 Oct 2026

Partner API

Let a voice assistant or phone system answer a driving school's everyday calls: what lessons cost, who teaches, when there's a free slot. It can also send the school booking requests and new enquiries.

How a call uses it

  1. 01

    Identify the caller

    Look up the caller ID with GET /v1/students/lookup. A match gives you their name, lessons left and next lesson.

  2. 02

    Answer from live data

    Prices from /v1/pricing, teachers from /v1/instructors, free times from /v1/availability. Nothing to sync; every call reads the school's current state.

  3. 03

    Hand the action to the school

    Known students: POST /v1/lesson-requests or /v1/cancellation-requests. Nothing free: POST /v1/waiting-list. New callers: POST /v1/leads. Staff approve these in the dashboard, so the agent never double-books.

Basics

Want a sandbox school with sample instructors, students and lessons? Ask us and we'll send you a test key.

Base URL
Shown below. All paths start with /v1.
Auth
Authorization: Bearer <key>. One key per school, created by the school in Settings → Integrations → API keys.
Format
JSON in, JSON out. Errors are { "error": { "code", "message" } }.
Times
Returned in the school's time zone with an offset. Sent times must include an offset too.
Ids
Opaque strings. Pass back exactly what the API returned.
Keys
Created by a school owner or admin, shown once, stored only as a hash, revocable at any time. Sample-data workspaces get av_test_ keys; real schools get av_live_.
Server only
Call the API from your servers. Browser requests are refused (no CORS), so a key can't leak through a web page.
Retries
Every GET is safe to repeat. POST /v1/leads and /v1/cancellation-requests are too: a repeat returns 200 with the existing record.
Isolation
A key only ever sees its own school. Ids from another school answer 404, the same as ids that don't exist.
# Base URL
https://school.autoviatest.com/api

curl "https://school.autoviatest.com/api/v1/pricing" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Endpoints

17 endpoints in 5 groups.

Setup

GET/v1/me

Check your key

Which school and key a request is authenticated as. mode is test while the school holds sample data and live once it runs on real records. Call it once when a partner saves a key.

Caller asksSetup: confirm the key a school pasted in works and belongs to the right school.

Query parameters

None.

Request

curl "https://school.autoviatest.com/api/v1/me" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "key": {
    "name": "Voice assistant",
    "preview": "av_live_3f9a",
    "mode": "live"
  },
  "school": {
    "id": "jd7f3kq9m2n8p4r6t1v5w0x3y",
    "name": "Autoescuela Sol",
    "timezone": "Europe/Madrid"
  }
}

School

GET/v1/school

School profile

Contact details, time zone, currency and booking rules for the school the key belongs to.

Caller asks"Where are you?" · "How far ahead do I need to book?" · "What's your cancellation policy?"

Query parameters

None.

Request

curl "https://school.autoviatest.com/api/v1/school" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "name": "Autoescuela Sol",
  "phone": "+34 910 000 000",
  "email": "hola@autoescuelasol.es",
  "address": "Calle Mayor 12, 28013, Madrid, ES",
  "timezone": "Europe/Madrid",
  "currency": "EUR",
  "defaultLessonDuration": 60,
  "bookingLeadTimeHours": 24,
  "cancellationPolicy": "Free cancellation up to 24 hours before the lesson."
}
GET/v1/pricing

Prices

Active lesson packages, cheapest first unless the school set an order. Prices are in major units of currency.

Caller asks"How much are lessons?" · "Do you have an intensive course?"

Query parameters

None.

Request

curl "https://school.autoviatest.com/api/v1/pricing" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "currency": "EUR",
  "packages": [
    {
      "id": "k57a1bq3h2m0v8c9x4r6t5y7z",
      "name": "10 lessons",
      "description": "Flexible scheduling, pickup included",
      "lessonCount": 10,
      "pricePerLesson": 38,
      "totalPrice": 380,
      "validityDays": 90,
      "lessonType": null
    }
  ]
}
GET/v1/instructors

Instructors

Active instructors with their regular weekly hours (dayOfWeek 0 = Sunday, times in the school's zone). phone is the instructor's own number; it is null unless the school turns on "Share instructor phone numbers" in its API key settings, or the instructor hasn't added one.

Caller asks"Who are the teachers?" · "Does Marta work on Saturdays?" · "Can I have Marta's number?"

Query parameters

None.

Request

curl "https://school.autoviatest.com/api/v1/instructors" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "instructors": [
    {
      "id": "j97c2mf8n1p4q6r3s5t7v9w0x",
      "name": "Marta Ruiz",
      "phone": "+34 611 222 333",
      "specializations": [
        "automatic",
        "nervous drivers"
      ],
      "bio": null,
      "averageRating": 4.8,
      "weeklyHours": [
        {
          "dayOfWeek": 1,
          "start": "09:00",
          "end": "14:00"
        },
        {
          "dayOfWeek": 1,
          "start": "16:00",
          "end": "20:00"
        }
      ]
    }
  ]
}
GET/v1/vehicles

Vehicles

The fleet a student can learn in. Registration, VIN and location are never returned. inService is false while a car is in the workshop.

Caller asks"Do you have automatic cars?" · "What car will I drive?"

Query parameters

None.

Request

curl "https://school.autoviatest.com/api/v1/vehicles" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "vehicles": [
    {
      "id": "n45b7cd9f1h3k5m7p9r1t3v5x",
      "make": "Seat",
      "model": "Ibiza",
      "year": 2023,
      "transmission": "automatic",
      "fuelType": "petrol",
      "color": "white",
      "inService": true
    }
  ]
}

Scheduling

GET/v1/availability

Free slots

Bookable start times per day, after removing existing lessons, approved time off and the school's booking lead time. Slots start every 30 minutes.

Caller asks"Is there anything Thursday afternoon?" · "When's the next free lesson with Marta?"

Query parameters

datedaterequired
First day, YYYY-MM-DD in the school's time zone.
daysinteger
Number of days to return, 1–14. Default 1.
durationinteger
Lesson length in minutes, 30–240. Default 60.
instructorIdstring
Only this instructor's slots.

Errors

  • 404 not_found instructorId is not an active instructor of this school.

Request

curl "https://school.autoviatest.com/api/v1/availability?date=2026-10-08" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "timezone": "Europe/Madrid",
  "duration": 60,
  "days": [
    {
      "date": "2026-10-08",
      "slots": [
        {
          "start": "2026-10-08T16:00:00+02:00",
          "end": "2026-10-08T17:00:00+02:00",
          "instructorId": "j97c2mf8n1p4q6r3s5t7v9w0x",
          "instructorName": "Marta Ruiz"
        }
      ]
    }
  ]
}
GET/v1/calendar

Lesson calendar

Every lesson booked across the school (or one instructor) for a date range, cancelled lessons left out. Students appear as first name and initial. Returns up to 500 lessons; truncated is true when there were more, so ask for fewer days.

Caller asks"Is Marta teaching this afternoon?" · A receptionist agent checking who's out on the road.

Query parameters

datedaterequired
First day, YYYY-MM-DD in the school's time zone.
daysinteger
Number of days, 1–14. Default 1.
instructorIdstring
Only this instructor's lessons.

Errors

  • 404 not_found instructorId is not an instructor of this school.

Request

curl "https://school.autoviatest.com/api/v1/calendar?date=2026-10-08" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "timezone": "Europe/Madrid",
  "lessons": [
    {
      "id": "q34f6hj8l0n2p4r6t8v0x2z4d",
      "start": "2026-10-06T10:00:00+02:00",
      "end": "2026-10-06T11:00:00+02:00",
      "status": "scheduled",
      "type": "standard",
      "instructorId": "j97c2mf8n1p4q6r3s5t7v9w0x",
      "instructorName": "Marta Ruiz",
      "student": "Lucía G.",
      "studentId": "m12d4hf6k8n0p2r4t6v8x0z2b",
      "pickupLocation": "Atocha station"
    }
  ],
  "truncated": false
}

Students

GET/v1/students/lookup

Find the caller

Students whose own or parent's phone number matches. International and local formats match each other (+34 612 345 678 = 612345678). Returns up to 5.

Caller asksGreet a known caller by name, tell them how many lessons they have left and when the next one is.

Query parameters

phonestringrequired
Caller ID, any format. At least 7 digits.

Request

curl "https://school.autoviatest.com/api/v1/students/lookup?phone=%2B34612345678" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "students": [
    {
      "id": "m12d4hf6k8n0p2r4t6v8x0z2b",
      "firstName": "Lucía",
      "lastName": "García",
      "status": "active",
      "matchedOn": "student_phone",
      "lessonsRemaining": 6,
      "nextLesson": {
        "id": "q34f6hj8l0n2p4r6t8v0x2z4d",
        "start": "2026-10-06T10:00:00+02:00",
        "duration": 60,
        "instructorName": "Marta Ruiz",
        "pickupLocation": "Atocha station"
      }
    }
  ]
}
GET/v1/students

Student directory

All students with their phone numbers, a page at a time. Pass nextCursor back as cursor until it is null; every page is full except the last. Use it to keep a phone system's contact list in step so staff see who's calling.

Caller asksNightly sync of caller names into the PBX phonebook.

Query parameters

limitinteger
Page size, 1–100. Default 50.
cursorstring
nextCursor from the previous page.
statusstring
Only active, inactive, completed or suspended students.

Errors

  • 400 invalid_request cursor was edited or belongs to a different status filter. Start again without it.

Request

curl "https://school.autoviatest.com/api/v1/students" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "students": [
    {
      "id": "m12d4hf6k8n0p2r4t6v8x0z2b",
      "firstName": "Lucía",
      "lastName": "García",
      "phone": "612 345 678",
      "parentPhone": null,
      "status": "active"
    }
  ],
  "nextCursor": "eyJpZCI6Im0xMmQ0aGY2..."
}
GET/v1/students/{id}

Student progress and balance

One student's contact numbers, progress (lessons done, hours, theory and practical test), active packages with lessons left, and any amount still owed. parentPhone is set for younger students whose parent handles bookings. testReadiness is 0–100 when the school tracks it.

Caller asks"How many lessons do I have left?" · "Have I paid everything?" · "Am I ready for the test?"

Path parameters

idstringrequired
Student id from lookup or the directory.

Errors

  • 404 not_found No such student in this school.

Request

curl "https://school.autoviatest.com/api/v1/students/<id>" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "id": "m12d4hf6k8n0p2r4t6v8x0z2b",
  "firstName": "Lucía",
  "lastName": "García",
  "phone": "612 345 678",
  "parentPhone": null,
  "status": "active",
  "preferredInstructor": {
    "id": "j97c2mf8n1p4q6r3s5t7v9w0x",
    "name": "Marta Ruiz"
  },
  "progress": {
    "completedLessons": 14,
    "drivingHours": 14,
    "theoryTestPassed": true,
    "practicalTestPassed": false,
    "testReadiness": 72
  },
  "lessonsRemaining": 6,
  "packages": [
    {
      "name": "20 lessons",
      "lessonsTotal": 20,
      "lessonsRemaining": 6,
      "expiresAt": "2026-12-31T23:00:00.000Z"
    }
  ],
  "balance": {
    "currency": "EUR",
    "amountDue": 120,
    "pendingPayments": 1
  }
}
GET/v1/lessons

A student's upcoming lessons

The next 20 lessons for a student, soonest first.

Caller asks"When are my lessons this week?"

Query parameters

studentIdstringrequired
From the lookup endpoint.

Errors

  • 404 not_found No such student in this school.

Request

curl "https://school.autoviatest.com/api/v1/lessons?studentId=<studentId>" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "lessons": [
    {
      "id": "q34f6hj8l0n2p4r6t8v0x2z4d",
      "start": "2026-10-06T10:00:00+02:00",
      "duration": 60,
      "status": "scheduled",
      "type": "standard",
      "instructorName": "Marta Ruiz",
      "pickupLocation": "Atocha station",
      "cancellationRequested": false
    }
  ]
}

Requests

POST/v1/lesson-requests

Request a lesson

Sends a booking request to the school's Lesson Requests inbox for staff to approve. Nothing is booked until they do, so the agent should say "I've passed your request to the school", not "you're booked". Same rules as the student portal: the student needs lessons left in a package, up to 3 options within the next 90 days, at most 5 requests waiting.

Caller asks"Can I have Thursday at 4 with Marta?"

Body

studentIdstringrequired
From the lookup endpoint.
preferredTimesarrayrequired
1–3 start times within 90 days, ISO 8601 with an offset. Use start values from /v1/availability. Duplicates are merged.
instructorIdstring
Preferred instructor.
durationinteger
Minutes, 30–240. Default 60.
lessonTypestring
Free text such as standard, motorway, test_prep, up to 40 characters. Default standard.
notesstring
Anything the caller added. Up to 500 characters.

Errors

  • 404 not_found Unknown student, or an instructor who isn't active at this school.
  • 409 no_lessons_remaining No lessons left in an active package. Offer one from /v1/pricing.
  • 429 too_many_pending_requests The student already has 5 requests waiting.

Request

curl -X POST "https://school.autoviatest.com/api/v1/lesson-requests" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "studentId": "m12d4hf6k8n0p2r4t6v8x0z2b",
    "preferredTimes": [
      "2026-10-08T16:00:00+02:00",
      "2026-10-09T16:00:00+02:00"
    ],
    "instructorId": "j97c2mf8n1p4q6r3s5t7v9w0x",
    "duration": 60,
    "notes": "Pickup at Atocha station, please."
  }'

Response · 201

{
  "lessonRequest": {
    "id": "s56h8jl0n2p4r6t8v0x2z4b6f",
    "status": "pending"
  }
}
GET/v1/lesson-requests

A student's lesson requests

The student's 20 most recent requests, newest first: pending, approved, scheduled (with the lesson that was booked), rejected (with the reason) or cancelled.

Caller asks"Did the school confirm my Thursday lesson?"

Query parameters

studentIdstringrequired
From the lookup endpoint.

Errors

  • 404 not_found No such student in this school.

Request

curl "https://school.autoviatest.com/api/v1/lesson-requests?studentId=<studentId>" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "lessonRequests": [
    {
      "id": "s56h8jl0n2p4r6t8v0x2z4b6f",
      "status": "scheduled",
      "preferredTimes": [
        "2026-10-08T16:00:00+02:00"
      ],
      "duration": 60,
      "lessonType": "standard",
      "createdAt": "2026-10-01T12:04:00+02:00",
      "rejectionReason": null,
      "scheduledLesson": {
        "id": "w90m2pr4t6v8x0z2b4d6f8h0k",
        "start": "2026-10-08T16:00:00+02:00"
      }
    }
  ]
}
POST/v1/lesson-requests/{id}/cancel

Withdraw a lesson request

Withdraws a request the school hasn't answered yet. No body.

Caller asks"Actually, forget Thursday."

Path parameters

idstringrequired
Lesson request id.

Errors

  • 404 not_found No such request in this school.
  • 409 request_not_pending The school already answered it. Use /v1/cancellation-requests for a booked lesson.

Request

curl -X POST "https://school.autoviatest.com/api/v1/lesson-requests/<id>/cancel" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY"

Response · 200

{
  "lessonRequest": {
    "id": "s56h8jl0n2p4r6t8v0x2z4b6f",
    "status": "cancelled"
  }
}
POST/v1/cancellation-requests

Ask to cancel a lesson

Flags an upcoming lesson for cancellation. Staff confirm it in the dashboard, where the school's cancellation policy applies. Safe to retry: a second call returns 200 and keeps the first reason.

Caller asks"I'm ill, can I cancel tomorrow's lesson?"

Body

lessonIdstringrequired
From /v1/lessons or nextLesson in the lookup.
reasonstring
Up to 500 characters.

Errors

  • 404 not_found No such lesson in this school.
  • 409 lesson_not_cancellable The lesson was cancelled, has started or is in the past.

Request

curl -X POST "https://school.autoviatest.com/api/v1/cancellation-requests" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "lessonId": "q34f6hj8l0n2p4r6t8v0x2z4d",
    "reason": "Caller is ill."
  }'

Response · 201

{
  "cancellationRequest": {
    "id": "q34f6hj8l0n2p4r6t8v0x2z4d",
    "cancellationRequested": true,
    "alreadyRequested": false
  }
}
POST/v1/waiting-list

Join the waiting list

Adds a caller to the school's waiting list with their preferred days and times, for when availability comes back empty. Send studentId for a known student, or firstName and phone for a new caller.

Caller asks"Nothing this week? Put me down for evenings, automatic."

Body

studentIdstring
Known student. Name and phone are taken from their record.
firstNamestring
Required without studentId.
phonestring
Required without studentId. At least 7 digits.
lastNamestring
Caller's last name.
emailstring
If the caller gave one.
preferredDaysinteger[]
Weekdays as numbers, 0 = Sunday … 6 = Saturday.
preferredTimeSlotsarray
Any of morning, afternoon, evening.
transmissionstring
manual or automatic.
instructorIdstring
Preferred instructor.
notesstring
Up to 500 characters.

Errors

  • 404 not_found Unknown student or instructor.
  • 409 already_on_waiting_list This student or phone number is already waiting or being contacted.

Request

curl -X POST "https://school.autoviatest.com/api/v1/waiting-list" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Ana",
    "phone": "+34 600 111 222",
    "preferredDays": [
      1,
      3
    ],
    "preferredTimeSlots": [
      "evening"
    ],
    "transmission": "automatic"
  }'

Response · 201

{
  "waitingListEntry": {
    "id": "y12p4rt6v8x0z2b4d6f8h0k2m",
    "status": "waiting",
    "position": 4
  }
}
POST/v1/leads

Record a new enquiry

Adds a caller who isn't a student yet to the school's Leads pipeline, optionally with a callback time. Safe to retry: if the number already has an open lead, that lead gets the new notes and callback time and the call returns 200 instead of 201.

Caller asks"I'd like to sign up, can someone call me back tomorrow morning?"

Body

firstNamestringrequired
Caller's first name.
phonestringrequired
At least 7 digits.
lastNamestring
Caller's last name.
emailstring
If the caller gave one. Must look like an email.
packageIdsarray
Up to 20 package ids from /v1/pricing the caller asked about.
callbackAtdate-time
When to call back: a future ISO 8601 time with an offset, within a year.
notesstring
Summary of the call. Up to 1000 characters.
sourcestring
Shown in the pipeline. Default api; voice_ai is a good choice.

Errors

  • 404 not_found A packageIds entry isn't a package of this school.

Request

curl -X POST "https://school.autoviatest.com/api/v1/leads" \
  -H "Authorization: Bearer $AUTOVIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Pablo",
    "phone": "+34 699 000 111",
    "packageIds": [
      "k57a1bq3h2m0v8c9x4r6t5y7z"
    ],
    "callbackAt": "2026-10-07T10:00:00+02:00",
    "notes": "Wants an intensive course before December. Has no theory test yet.",
    "source": "voice_ai"
  }'

Response · 201

{
  "lead": {
    "id": "u78k0mn2p4r6t8v0x2z4b6d8h",
    "status": "new",
    "duplicate": false
  }
}

Errors on every endpoint

Check the HTTP status first. The code is stable; the message is for people and may change.

400 invalid_request
A parameter is missing or malformed. message says which.
401 unauthorized
Missing, wrong or revoked API key.
403 school_not_writable
Write calls only: the school's trial ended or its account is suspended.
429 rate_limited
More than 120 requests a minute for this key (bursts of 60 allowed), or too many bad keys from one IP. Wait for the Retry-After header's seconds.
500 internal_error
Unexpected failure. Safe to retry reads.

Not in v1 yet

  • Confirmed bookings without staff approval. Requests go to the school's inbox first.
  • Webhooks when a request is approved or a lesson changes. Poll /v1/lesson-requests or /v1/calendar for now.
  • Paying for a package over the phone. /v1/students/{id} tells the agent what is owed.
  • Messages to a specific instructor.
  • Partner-level keys that cover several schools. Each school issues its own key.