Bulk Import Appointments
POST /api/appointment_schedule/bulk
Import appointment schedules. The endpoint accepts either a JSON array sent directly as the request body or a file upload (Excel .xlsx, CSV .csv, or JSON .json). Supports synchronous and background (Celery) processing modes — both run the same import logic and return the same result shape.
Processing Mode
Both modes share the same import business logic; only the result delivery differs.
| Mode | How to select | Response | Use when |
|---|---|---|---|
background (default) |
Omit the parameter | 202 + background_task_uuid to poll |
Large imports or when you don't need the result immediately |
sync |
JSON: ?processing_mode=sync — File: form field processing_mode=sync
|
200 + full result inline |
Small imports when you want the result in the same request |
sync mode you get the result directly and can skip the
Background Processing endpoints.
Request Body — JSON
Send a JSON array of objects directly as the request body (Content-Type:
application/json).
processing_mode is passed as a query parameter in this mode:
| Parameter | Type | Required | Description |
|---|---|---|---|
tag_name |
string | Yes | QR code tag name |
tag_number |
string | Yes | QR code tag number |
start_date_time |
string | Yes | Appointment start date/time (YYYY-MM-DD HH:mm) |
location |
string | Yes | Full address of the appointment |
duration |
integer | No | Duration in minutes (Default 60 mins) |
service |
string | No | Service of the appointment (Either service or service code is required) |
service_code |
string | No | Service code of the appointment (Either service or service code is required) |
timezone_name |
string | No | Timezone name (e.g. Australia/Melbourne) |
job_reference_id |
string | No | External job/reference identifier |
organization_uuid |
string | Yes | UUID of the organization |
Example — JSON
[
{
"tag_name": "dest15",
"tag_number": "Sync-15",
"start_date_time": "2026-08-20T10:00:00",
"location": "78 Garden Grove Parade, 3 unit, Adamstown Heights, New South Wales 2289, Australia",
"duration": 20,
"service": "Consultation",
"timezone_name": "Australia/Melbourne",
"job_reference_id": "JOB-0001",
"organization_uuid": "Po5fQfUGec5ucKFeMDes24"
}
]
Request Body — File
Upload an Excel, CSV, or JSON file (multipart/form-data):
| Parameter | Type | Required | Description |
|---|---|---|---|
file |
file | Yes | Excel (.xlsx), CSV (.csv), or JSON (.json) file containing appointment data |
organization_uuid |
string | Yes | UUID of the organization to import appointments for |
org_identifier |
string | No | Slug identifying the import handler (e.g. monash_health, default) |
processing_mode |
string | No | Processing mode: background (Celery, default) or sync (blocking) |
Example — File
curl -X POST /api/appointment_schedule/bulk \
-F "file=@appointments.xlsx" \
-F "organization_uuid=XYZ789UVW123RST456MNOP" \
-F "processing_mode=background"
See Errors & Rate Limits for the common error contract used across the API.
Error Codes
| Status | Meaning |
|---|---|
| 200 | Import complete (sync mode) |
| 202 | Processing started (background mode) |
| 400 | Bad Request — missing file/body or invalid parameters |
| 401 | Unauthorized |
| 403 | Permission denied |
| 500 | Internal Server Error |
Example Request — JSON
curl -X POST "http://staging.didyougo.com.au/api/appointment_schedule/bulk?processing_mode=sync" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_api_key:your_api_secret" \
-d '[
{
"tag_name": "dest15",
"tag_number": "Sync-15",
"start_date_time": "2026-08-20T10:00:00",
"location": "78 Garden Grove Parade, 3 unit, Adamstown Heights, New South Wales 2289, Australia",
"duration": 20,
"service": "Consultation",
"timezone_name": "Australia/Melbourne",
"job_reference_id": "JOB-0001",
"organization_uuid": "Po5fQfUGec5ucKFeMDes24"
}
]'
Try It
Requests are sent without cookies — you must provide a valid Bearer <api_key>:<api_secret> header.
Click the Send API Request button above and see the response here!
Example Request — File
curl -X POST http://staging.didyougo.com.au/api/appointment_schedule/bulk \
-H "Authorization: Bearer your_api_key:your_api_secret" \
-F "file=@appointments.xlsx" \
-F "organization_uuid=org-uuid-here" \
-F "processing_mode=background"
Try It
Requests are sent without cookies — you must provide a valid Bearer <api_key>:<api_secret> header.
Click the Send API Request button above and see the response here!
Example Response (Background)
{
"message": "Bulk import started in background (Celery).",
"task_id": "celery-task-id-here",
"background_task_uuid": "DEF789GHI012JKL345MNOP"
}
Poll /api/background-tasks/uuid/{background_task_uuid} until the status is
COMPLETED or FAILED. See Background
Processing for the full flow.
Example Response (Sync)
{
"appointment_schedules_upserted": [
{
"organization_uuid": "Po5fQfUGec5ucKFeMDes24",
"qr_code_uuid": "9kp4uYEhERwDEi6VDWXTYw",
"qr_code_tag_uuid": "nTCCBKWHoTMGcJvMP7QaNM",
"service": "Consultation",
"appointment_date": "2026-08-20",
"start_date_time": "2026-08-20T10:00:00+10:00",
"end_date_time": "2026-08-20T10:30:00+10:00",
"duration": 30,
"all_day": false,
"no_date_time_provided": false,
"job_reference_id": "JOB-0001",
"type": "SERVICE"
}
],
"excluded_appointments": []
}
excluded_appointments contains one entry per rejected row with its index, data,
and error_message.