[gtranslate]

US Virtual Notary - Developers Guide: REST API Reference (v3)

Programmatic access to create, read, and manage resources such as appointments, reservations, documents, signers and videos.

Base URL & Versioning

Base: https://usvirtualnotary.com/wp-json/v3
Status: Stable

All endpoints are prefixed with /wp-json/v3. Older versions remain available but may be deprecated over time.

Authentication

v3 uses bearer tokens (no Basic Auth). Include your token in the Authorization header.

Authorization: Bearer YOUR_TOKEN

Errors

We use standard HTTP status codes. Error bodies include a short code and message.

{
    "error": {
        "code": "invalid_request",
        "message": "Missing required parameter: id"
    }
}

Pagination

List endpoints support cursor-based pagination with limit (default 25, max 100).

GET https://usvirtualnotary.com/wp-json/v3/appointments?limit=25&cursor=eyJwYWdlIjoxfQ=

Rate Limits

Reasonable default limits apply. Responses include X-RateLimit-* headers when relevant.


List Appointments

GET /wp-json/v3/appointments

Path / Query Parameters

NameInTypeRequiredDescription
limitqueryintegerNoMaximum number of items per page (1–100). Default 25.
cursorquerystringNoOpaque pagination cursor. Base64-encoded object of the form {"after": <internal_id>}.
statusquerystringNoFilter by appointment status. Accepted values: scheduled, completed, canceled.

Request (example)

curl -sS \
  -H "Authorization: Bearer YOUR_TOKEN" \
  "https://usvirtualnotary.com/wp-json/v3/appointments?limit=2&status=scheduled"

Response (200)

{
    "object": "list",
    "data": [
        {
            "object": "appointment",
            "id": 275867,
            "status": "complete",
            "timestamp": "2025-08-24T18:27:45+00:00",
            "timezone": "America/New_York",
            "service": "remote",
            "signing_method": "remote",
            "quantity": 1,
            "customer": {
                "first_name": "John",
                "last_name": "Doe",
                "email": "john.doe@example.com"
            },
            "lang": "en",
            "keys": {
                "appointment": "DgnlniHMkEbEl6UAGEFLp",
                "upload": "X67RAgOKzCj61sWHVHLWm",
                "session": "k4Njq7zyGbmG1mHsKRqn6"
            },
            "links": {
                "self": "https://usvirtualnotary.com/wp-json/v3/appointments/275867"
            }
        }
    ],
    "next_cursor": "eyJhZnRlciI6IDEyMzQ1fQ=="
}

Response (error)

{
    "error": {
        "code": "not_found",
        "message": "Appointment not found."
    }
}

Get Appointment

GET /wp-json/v3/appointments/{id}

Path / Query Parameters

NameInTypeRequiredDescription
idpathintegerYesAppointment ID.

Request (example)

curl -sS \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  https://usvirtualnotary.com/wp-json/v3/appointments/823451

Response (200)

{
    "object": "appointment",
    "id": 275867,
    "status": "scheduled",
    "timestamp": "2024-04-24T18:27:45+00:00",
    "timezone": "America/New_York",
    "service": "remote",
    "signing_method": "remote",
    "quantity": 1,
    "customer": {
        "first_name": "John",
        "last_name": "Doe",
        "email": "john.doe@example.com"
    },
    "lang": "en",
    "keys": {
        "appointment": "DgnlniHMkEbEl6UAGEFLp",
        "upload": "X67RAgOKzCj61sWHVHLWm",
        "session": "k4Njq7zyGbmG1mHsKRqn6"
    },
    "links": {
        "self": "https://usvirtualnotary.com/wp-json/v3/appointments/275867"
    }
}

Response (error)

{
    "error": {
        "code": "not_found",
        "message": "Appointment not found."
    }
}

Update Appointment

POST /wp-json/v3/appointments/{id}

Path / Query Parameters

NameInTypeRequiredDescription
first_namebodystringNoCustomer first name.
last_namebodystringNoCustomer last name.
emailbodystringNoCustomer email address.

Request (example)

curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Alice",
    "last_name": "Johnson",
    "email": "alice.johnson@example.com"
  }' \
  "https://usvirtualnotary.com/wp-json/v3/appointments/12345"

Response (200)

{
    "object": "appointment",
    "id": 12345,
    "status": "scheduled",
    "customer": {
        "first_name": "John",
        "last_name": "Doe",
        "email": "john.doe@example.com"
    }
}

Response (error)

{
    "code": "not_found",
    "message": "Appointment not found.",
    "data": {
        "status": 404
    }
}

Reschedule Appointment

POST /wp-json/v3/appointments/{id}/reschedule

Path / Query Parameters

NameInTypeRequiredDescription
idpathintegerYesAppointment ID.
timestampbodyintegerYesNew appointment start time as UNIX epoch seconds (UTC).
timezonebodystringYesIANA timezone for the provided timestamp, e.g. "America/New_York".

Request (example)

curl -sS \
  -X PATCH \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"timestamp": 1767357000, "timezone": "America/New_York"}' \
  'https://usvirtualnotary.com/wp-json/v3/appointments/123/reschedule'

Response (200)

{
    "object": "appointment",
    "id": 123,
    "status": "scheduled",
    "timestamp": "2024-04-24T18:27:45+00:00",
    "timezone": "America/New_York",
    "service": "general_notary",
    "signing_method": "remote",
    "quantity": 1,
    "customer": {
        "first_name": "Alice",
        "last_name": "Smith",
        "email": "alice@example.com"
    },
    "lang": "en",
    "keys": {
        "appointment": "appt_key_123",
        "upload": "upload_key_abc",
        "session": "sess_key_xyz"
    },
    "links": {
        "self": "https://usvirtualnotary.com/wp-json/v3/appointments/123"
    }
}

Response (error)

{
    "error": {
        "code": "reschedule_failed",
        "message": "Unable to reschedule appointment."
    }
}

Check Availability

GET /wp-json/v3/appointments/availability

Path / Query Parameters

NameInTypeRequiredDescription
datequerystringNoTarget date in YYYY-MM-DD format. If omitted or invalid, defaults to today.
timezonequerystringNoIANA timezone string (e.g., "America/New_York").
remotequeryintegerNoInclude remote notary slots. 1 = true.
enotaryqueryintegerNoInclude enotary slots. 1 = true.
wetqueryintegerNoInclude wet-signature slots. 1 = true. (Legacy)
internationalqueryintegerNoInclude international notary slots. 1 = true.
apostillequeryintegerNoInclude apostille slots. 1 = true.

Request (example)

curl -sS \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  'https://usvirtualnotary.com/wp-json/v3/appointments/availability?date=2025-03-02&timezone=America/Chicago&remote=0&enotary=1&wet=0&international=0&apostille=1'

Response (200)

{
  "object": "availability",
  "date": "2025-03-02",
  "timezone": "America/New_York",
  "utc_offset": -4,
  "availability": {
    "0900-0915": true,
    "0915-0930": false,
    "0930-0945": true,
    "0945-1000": true
    // ... keys for the whole day at 15-minute intervals
  }
}

Response (error)

{
    "error": {
        "code": "no_workspace",
        "message": "Token not scoped to a workspace."
    }
}

List Reservations

GET /wp-json/v3/reservations

Path / Query Parameters

NameInTypeRequiredDescription
limitqueryintegerNoMaximum number of items per page (1–100). Default 25.
cursorquerystringNoOpaque pagination cursor. Base64-encoded object of the form {"after": <internal_id>}.
statusquerystringNoFilter by reservation status. Accepted values: draft, pending, queued, scheduled, completed, canceled.

Request (example)

curl -sS \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  'https://usvirtualnotary.com/wp-json/v3/reservations?limit=25&status=scheduled'

Response (200)

{
    "object": "list",
    "data": [
        {
            "object": "reservation",
            "id": 5821,
            "status": "scheduled",
            "timestamp_created": "2025-08-24T14:05:32+00:00",
            "service": "remote",
            "signing_method": "remote",
            "quantity": 2,
            "prepaid": true,
            "customer": {
                "first_name": "Alice",
                "last_name": "Signer",
                "email": "alice@example.com"
            },
            "lang": "en",
            "keys": {
                "appointment": "appt_key_456def"
            },
            "links": {
                "self": "https://usvirtualnotary.com/wp-json/v3/reservations/5821"
            }
        }
    ],
    "next_cursor": "eyJhZnRlciI6IDU4MjF9"
}

Response (error)

{
    "error": {
        "code": "no_workspace",
        "message": "Token not scoped to a workspace."
    }
}

Get Reservation

GET /wp-json/v3/reservations/{id}

Path / Query Parameters

NameInTypeRequiredDescription
idpathintegerYesReservation ID.

Request (example)

curl -sS \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  https://usvirtualnotary.com/wp-json/v3/reservations/5821

Response (200)

{
    "object": "reservation",
    "id": 5821,
    "status": "scheduled",
    "timestamp_created": "2025-08-24T14:05:32+00:00",
    "service": "remote",
    "signing_method": "remote",
    "quantity": 2,
    "prepaid": true,
    "customer": {
        "first_name": "Alice",
        "last_name": "Signer",
        "email": "alice@example.com"
    },
    "lang": "en",
    "keys": {
        "reservation": "rsv_key_123abc"
    },
    "links": {
        "self": "https://usvirtualnotary.com/wp-json/v3/reservations/5821"
    }
}

Response (error)

{
    "error": {
        "code": "not_found",
        "message": "Reservation not found."
    }
}

Update Reservation

POST /wp-json/v3/reservations/{id}

Path / Query Parameters

NameInTypeRequiredDescription
first_namebodystringNoCustomer first name.
last_namebodystringNoCustomer last name.
emailbodystringNoCustomer email address.
statusbodystringNoReservation status. Cannot be 'canceled' (use Cancel endpoint).
langbodystringNoLanguage code (e.g. 'en').

Request (example)

curl -X PATCH https://usvirtualnotary.com/wp-json/v3/reservations/275839 \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane.doe@example.com",
    "status": "scheduled",
    "lang": "en"
  }'

Response (200)

{
    "object": "reservation",
    "id": 275839,
    "status": "scheduled",
    "created_at": "2025-08-25T18:27:45+00:00",
    "service": "remote",
    "signing_method": "remote",
    "quantity": 1,
    "appointment_id": 823451,
    "prepaid": false,
    "customer": {
        "first_name": "Jane",
        "last_name": "Doe",
        "email": "jane.doe@example.com"
    },
    "lang": "en",
    "keys": {
        "appointment": "ABC123XYZ"
    },
    "documents": [],
    "links": {
        "self": "https://usvirtualnotary.com/wp-json/v3/reservations/275839"
    }
}

Response (error)

{
    "error": {
        "code": "not_found",
        "message": "Reservation not found."
    }
}

Cancel Reservation

POST /wp-json/v3/reservations/{id}/cancel

Path / Query Parameters

NameInTypeRequiredDescription
idpathintegerYesReservation ID.

Request (example)

curl -sS \
  -X POST \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  https://usvirtualnotary.com/wp-json/v3/reservations/5821/cancel

Response (200)

{
    "object": "reservation",
    "id": 5821,
    "status": "canceled"
}

Response (error)

{
    "error": {
        "code": "unable_to_cancel",
        "message": "Unable to cancel reservation."
    }
}

Create Reservation

POST /wp-json/v3/reservations

Path / Query Parameters

NameInTypeRequiredDescription
first_namebodystringYesCustomer first name.
last_namebodystringYesCustomer last name.
emailbodystringYesCustomer email address (optional).
servicebodystringYesService handle (e.g., "enotary").
signing_methodbodystringNoSigning method (e.g., "remote", "enotary").
signer_countbodyintegerNoNumber of signers (default 1).
quantitybodyintegerNoReservation quantity (default 1).
prepaidbodyintegerNo1 if prepaid, 0 otherwise.
langbodystringNoLanguage code (default "en").
statusbodystringNoInitial reservation status (default "draft").

Request (example)

curl -sS -X POST \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane@example.com",
    "service": "general-notary",
    "signing_method": "remote",
    "signer_count": 1,
    "quantity": 1,
    "prepaid": 0,
    "lang": "en",
    "status": "draft"
  }' \
  https://usvirtualnotary.com/wp-json/v3/reservations

Response (200)

{
    "object": "reservation",
    "id": 275840,
    "links": {
        "self": "https://usvirtualnotary.com/wp-json/v3/reservations/275840"
    }
}

Response (error)

{
    "code": "forbidden",
    "message": "Insufficient scope: reservations:write",
    "data": {
        "status": 403
    }
}

List Documents

GET /wp-json/v3/documents

Path / Query Parameters

NameInTypeRequiredDescription
limitqueryintegerNoMax items to return (1–100).
cursorquerystringNoOpaque pagination cursor (base64 of {"after":<internal_id>}).
appointment_idqueryintegerNoFilter by linked appointment id.
typequerystringNoFilter by document type (exact match).

Request (example)

curl -sS \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  'https://usvirtualnotary.com/wp-json/v3/documents?limit=10'

Response (200)

{
    "object": "list",
    "data": [
        {
            "object": "document",
            "id": 9876,
            "created_at": "2025-02-14T18:22:15Z",
            "type": "notarized",
            "filename": "signed-consent.pdf",
            "file_size": 204812,
            "appointment_id": 4321,
            "links": {
                "self": "https://usvirtualnotary.com/wp-json/v3/documents/9876"
            }
        }
    ],
    "next_cursor": "eyJhZnRlciI6OTg3NX0="
}

Response (error)

[
    {
        "status": 403,
        "code": "no_workspace",
        "message": "Token not scoped to a workspace."
    },
    {
        "status": 403,
        "code": "forbidden",
        "message": "Insufficient scope: documents:read"
    }
]

Get Document

GET /wp-json/v3/documents/{id}

Path / Query Parameters

NameInTypeRequiredDescription
idpathintegerYesDocument ID.

Request (example)

curl -sS \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  'https://usvirtualnotary.com/wp-json/v3/documents/12345?disposition=inline&expires=1800'

Response (200)

{
    "object": "document",
    "id": 9876,
    "created_at": "2025-02-14T18:22:15Z",
    "type": "notarized",
    "filename": "signed-consent.pdf",
    "file_size": 204812,
    "appointment_id": 4321,
    "signed_url": "https://s3.amazonaws.com/usvn-documents/signed-consent.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...",
    "signed_url_expires_at": "2025-02-14T20:22:15Z",
    "links": {
        "self": "https://usvirtualnotary.com/wp-json/v3/documents/9876"
    }
}

Response (error)

[
    {
        "status": 403,
        "code": "no_workspace",
        "message": "Token not scoped to a workspace."
    },
    {
        "status": 403,
        "code": "forbidden",
        "message": "Insufficient scope: documents:read"
    },
    {
        "status": 404,
        "code": "not_found",
        "message": "Document not found."
    }
]

Upload Document

POST /wp-json/v3/documents

Path / Query Parameters

NameInTypeRequiredDescription
object_typebodystringYesType of object the document is linked to. One of 'appointment' or 'reservation'.
object_idbodyintegerYesThe ID of the appointment or reservation.
filenamebodystringYesOriginal filename. Will be sanitized and stored as '<epoch>-<name>.pdf'.
pdf_contentbodystringYesBase64-encoded PDF file content.
typebodystringNoDocument type. Defaults to 'uploaded'. For reservations, this will always be forced to 'reservation'.

Request (example)

curl -sS \
  -X POST \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "object_type": "appointment",
    "object_id": 4321,
    "filename": "signed-consent.pdf",
    "pdf_content": "JVBERi0xLjQKJcKlwrHDqwoKMSAwIG9iago8PC9U..."
  }' \
  https://usvirtualnotary.com/wp-json/v3/documents

Response (200)

{
    "object": "document",
    "id": 9876,
    "created_at": "2024-06-28T14:05:32+00:00",
    "type": "uploaded",
    "filename": "1735249587-signed-consent.pdf",
    "file_size": 204812,
    "links": {
        "self": "https://usvirtualnotary.com/wp-json/v3/documents/9876",
        "appointment": "https://usvirtualnotary.com/wp-json/v3/appointments/4321",
        "reservation": null
    }
}

Response (error)

{
    "code": "bad_payload",
    "message": "Invalid or empty pdf_content (base64)."
}

List Videos

GET /wp-json/v3/videos

Path / Query Parameters

NameInTypeRequiredDescription
limitqueryintegerNoMax items (1…100). Default 25.
cursorquerystringNoOpaque cursor for pagination (base64 of {"after":<internal_id>}).
appt_idqueryintegerNoOptional filter: appointment ID.

Request (example)

curl -sS \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  'https://usvirtualnotary.com/wp-json/v3/videos?limit=10'

Response (200)

{
    "object": "list",
    "data": [
        {
            "object": "video",
            "id": 182,
            "appointment_id": 823451,
            "created_at": "2025-08-24T18:27:45+00:00",
            "filename": "session-recording.mp4",
            "file_size": 253687233,
            "links": {
                "self": "https://usvirtualnotary.com/wp-json/v3/videos/182",
                "appointment": "https://usvirtualnotary.com/wp-json/v3/appointments/823451"
            }
        }
    ],
    "next_cursor": null
}

Response (error)

{
    "error": {
        "code": "no_workspace",
        "message": "Token not scoped to a workspace."
    }
}

Get Video

GET /wp-json/v3/video/{id}

Path / Query Parameters

NameInTypeRequiredDescription
idpathintegerYesVideo ID.

Request (example)

curl -sS \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  'https://usvirtualnotary.com/wp-json/v3/videos/67890?disposition=attachment'

Response (200)

{
    "object": "video",
    "id": 182,
    "appointment_id": 823451,
    "created_at": "2025-08-24T18:27:45Z",
    "filename": "session-recording.mp4",
    "file_size": 253687233,
    "signed_url": "https://s3.amazonaws.com/usvn-videos/session-recording.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...",
    "signed_url_expires_at": "2025-08-24T20:27:45Z",
    "links": {
        "self": "https://usvirtualnotary.com/wp-json/v3/videos/182",
        "appointment": "https://usvirtualnotary.com/wp-json/v3/appointments/823451"
    }
}

Response (error)

{
    "error": {
        "code": "not_found",
        "message": "Video not found."
    }
}