How to update a partner appointment with trip
This document explains how to update an existing appointment and its pickup/dropoff trips using the Partner v2 endpoint.
Use this endpoint when the request includes a pickup or dropoff trip operation. If you only need to update appointment fields and do not want to create, update, or delete a trip, use the standard appointment update API instead.
To update an appointment with trip, you first need your credentials. If you don't already have one, head over to the Authentication and Authorization page to see how you can request credentials from us.
Request
HTTP request
PUT https://api.mykaarma.com/appointment/v2/dealers/{dealerUuid}/partner-appointments-with-trip/{sarUUID}
?enforcePreferences={enforcePreferences}
Parameters
Path parameters
| Parameter Name | Value | Description | Required |
|---|---|---|---|
dealerUuid | String | Unique identifier of the dealer | Yes |
sarUUID | String | UUID of the service appointment request to update | Yes |
Query parameters
| Parameter Name | Value | Description | Required |
|---|---|---|---|
enforcePreferences | Boolean | Whether to enforce dealer appointment preferences during update | No |
Authorization
| Scope | Level | Description |
|---|---|---|
appointment.create | Dealer | Authorises client to update appointment and trip data for the provided dealer |
Request Body
The request body is an UpdateAppointmentWithTripPartnerRequest. It uses the same flat partner contract as create, with trip UUIDs carried inside the trip objects:
| Property Name | Value | Description | Required |
|---|---|---|---|
customerUUID | String | Unique token assigned to the customer in myKaarma | Yes |
appointmentDateTime | String | Appointment date-time in ISO-8601 format with timezone offset | Yes |
dealerDepartmentUUID | String | UUID of the dealer department | Yes |
appointmentInformation | Object | Appointment details to save | Yes |
vehicleInformation | Object | Vehicle details for the appointment | No |
pickupTripInformation | Object | Pickup trip create/update/delete instruction. The pickup trip UUID is sent as pickupTripInformation.eventUUID. | Conditional |
dropTripInformation | Object | Dropoff trip create/update/delete instruction. The dropoff trip UUID is sent as dropTripInformation.eventUUID. | Conditional |
pickupDeliveryTripMetadata | Object | Metadata such as subTransportOptionRequest. Do not send trip UUIDs in this object for partner update. | No |
requesterUserUUID | String | UUID of the user making the request. Passed to the downstream PnD service, which requires it whenever source is not WEB. | Conditional — required unless source is WEB |
source | String | Platform source of the request. If WEB, downstream validations (including the requesterUserUUID requirement) are relaxed. Common values: WEB, DEALER_APP. | No |
appointmentMetaData | Object | Metadata of the appointment | No |
locale | String | Customer's language preference, for example en-US or fr-CA | No |
At least one trip operation must be present. Appointment-only updates are not supported by this endpoint.
To find the current pickup and dropoff trip UUIDs for an appointment, call get partner trips for an appointment before update.
For the full appointment, vehicle, and sub-transport field descriptions, see create a partner appointment with trip. The update endpoint uses the same field names.
appointmentDateTime
Send the updated appointment date and time as a single top-level value with timezone offset, for example:
2026-06-03T11:00:00-0700
The API uses this value to update the appointment and to derive trip appointment timing where required.
How Trip Operations Are Decided
For update, eventUUID is the trip identifier. A trip object with only eventUUID is treated as a delete marker.
| Trip object | eventUUID | Other trip fields | Operation |
|---|---|---|---|
| Absent | No | No | No operation |
| Present | No | Yes | Create trip |
| Present | Yes | No | Delete trip |
| Present | Yes | Yes | Update trip |
For pickup, use:
pickupTripInformation.eventUUID
For dropoff, use:
dropTripInformation.eventUUID
Do not send top-level tripUUID or dropoffTripUUID in partner requests.
Other trip fields include values such as rideType, rideTime, mustStartBy, address, location, driver, loaner, and optional field data. For delete, send only the relevant eventUUID.
pickupTripInformation
Use pickupTripInformation for the pickup trip.
| Property Name | Value | Description | Required |
|---|---|---|---|
eventUUID | String | Existing pickup trip UUID. Required for pickup update and pickup delete. Omit for pickup create. | Conditional |
rideType | String | Must be PICKUP_VEHICLE when a pickup body is sent. If omitted during pickup create/update, the API defaults it to PICKUP_VEHICLE. | No |
mustStartBy | String | Latest start time for the pickup trip in ISO-8601 format with timezone offset | No |
originAddress | String | Pickup origin address | No |
originLocationLat | Double | Latitude of the pickup origin | No |
originLocationLon | Double | Longitude of the pickup origin | No |
destinationAddress | String | Pickup destination address | No |
destLocationLat | Double | Latitude of the pickup destination | No |
destLocationLon | Double | Longitude of the pickup destination | No |
optionalFields | Map<String, String> | Additional optional key-value pairs | No |
For pickup delete, send:
{
"pickupTripInformation": {
"eventUUID": "{{pickup_trip_uuid}}"
}
}
dropTripInformation
Use dropTripInformation for the linked dropoff trip.
| Property Name | Value | Description | Required |
|---|---|---|---|
eventUUID | String | Existing dropoff trip UUID. Required for dropoff update and dropoff delete. Omit for dropoff create. | Conditional |
rideType | String | Must be DROPOFF_VEHICLE when a dropoff body is sent. If omitted during dropoff create/update, the API defaults it to DROPOFF_VEHICLE. | No |
rideTime | String | Scheduled time for the dropoff trip in ISO-8601 format with timezone offset | Yes, when creating or updating dropoff |
mustStartBy | String | Latest start time for the dropoff trip in ISO-8601 format with timezone offset | No |
originAddress | String | Dropoff origin address | No |
originLocationLat | Double | Latitude of the dropoff origin | No |
originLocationLon | Double | Longitude of the dropoff origin | No |
optionalFields | Map<String, String> | Additional optional key-value pairs | No |
For dropoff delete, send:
{
"dropTripInformation": {
"eventUUID": "{{dropoff_trip_uuid}}"
}
}
Operation Case Table
In the table below:
Pickup UUIDmeanspickupTripInformation.eventUUID.Pickup BodymeanspickupTripInformationcontains operational fields other thaneventUUID.Dropoff UUIDmeansdropTripInformation.eventUUID.Dropoff BodymeansdropTripInformationcontains operational fields other thaneventUUID.
| # | Pickup UUID | Pickup Body | Dropoff UUID | Dropoff Body | Result |
|---|---|---|---|---|---|
| 1 | No | No | No | No | Invalid. No trip operation specified. |
| 2 | No | No | No | Yes | Create dropoff for the pickup already mapped to the appointment. Invalid if no mapped pickup exists or a dropoff already exists. |
| 3 | No | No | Yes | No | Delete dropoff if it is linked to the appointment's mapped pickup. |
| 4 | No | No | Yes | Yes | Update dropoff if it is linked to the appointment's mapped pickup. |
| 5 | Yes | No | No | No | Delete pickup and cascade delete any linked dropoff. |
| 6 | Yes | No | No | Yes | Processed as pickup delete. Linked dropoff is cascade deleted; dropoff body is ignored. Prefer not to send this shape. |
| 7 | Yes | No | Yes | No | Delete pickup and delete the linked dropoff. |
| 8 | Yes | No | Yes | Yes | Processed as pickup delete. Linked dropoff is cascade deleted; dropoff body is ignored. Prefer not to send this shape. |
| 9 | No | Yes | No | No | Create pickup. Valid only if the appointment does not already have a mapped pickup. |
| 10 | No | Yes | No | Yes | Create pickup and create linked dropoff. Valid only if the appointment does not already have a mapped pickup. |
| 11 | No | Yes | Yes | No | Invalid. Cannot reference an existing dropoff while creating a new pickup. |
| 12 | No | Yes | Yes | Yes | Invalid. Cannot update an existing dropoff while creating a new pickup. |
| 13 | Yes | Yes | No | No | Update pickup. |
| 14 | Yes | Yes | No | Yes | Update pickup and create linked dropoff. |
| 15 | Yes | Yes | Yes | No | Update pickup and delete linked dropoff. |
| 16 | Yes | Yes | Yes | Yes | Update pickup and update linked dropoff. |
Validation Rules
- Existing pickup
eventUUIDmust match the pickup trip mapped to the appointment. - Existing dropoff
eventUUIDmust be linked to the same pickup trip. - Creating a dropoff fails if a dropoff is already linked to that pickup.
- Creating a pickup fails if the appointment already has a mapped pickup.
- If pickup is deleted, the linked dropoff is deleted as part of the same operation.
pickupTripInformation.rideTypemust bePICKUP_VEHICLEwhen a pickup body is sent.dropTripInformation.rideTypemust beDROPOFF_VEHICLEwhen a dropoff body is sent.dropTripInformation.rideTimeis required whendropTripInformationrepresents a dropoff create or update.- If pickup or dropoff trip data is present, the appointment transport option must be Pickup and Delivery. When the transport option is omitted, the API normalizes it to Pickup and Delivery.
Common Payload Patterns
Update pickup only
{
"customerUUID": "{{customer_uuid}}",
"appointmentDateTime": "2026-06-03T11:00:00-0700",
"dealerDepartmentUUID": "{{department_uuid}}",
"source": "WEB",
"pickupTripInformation": {
"eventUUID": "{{pickup_trip_uuid}}",
"rideType": "PICKUP_VEHICLE",
"mustStartBy": "2026-06-03T10:30:00-0700",
"originAddress": "123 Customer Street, Long Beach, CA"
},
"appointmentInformation": {
"customerAppointmentPreference": {
"emailConfirmation": true,
"textConfirmation": true
}
}
}
Update pickup and create dropoff
{
"customerUUID": "{{customer_uuid}}",
"appointmentDateTime": "2026-06-03T11:00:00-0700",
"dealerDepartmentUUID": "{{department_uuid}}",
"source": "WEB",
"pickupTripInformation": {
"eventUUID": "{{pickup_trip_uuid}}",
"rideType": "PICKUP_VEHICLE",
"mustStartBy": "2026-06-03T10:30:00-0700"
},
"dropTripInformation": {
"rideType": "DROPOFF_VEHICLE",
"rideTime": "2026-06-06T15:00:00-0700",
"mustStartBy": "2026-06-06T14:45:00-0700",
"originAddress": "100 W Broadway Suite 300, Long Beach, CA 90802, USA",
"originLocationLat": 33.7689325,
"originLocationLon": -118.1930229
},
"appointmentInformation": {
"customerAppointmentPreference": {
"emailConfirmation": true,
"textConfirmation": true
}
}
}
Update pickup and update dropoff
Send both pickupTripInformation and dropTripInformation with their existing eventUUIDs plus at least one operational field on each side.
{
"customerUUID": "{{customer_uuid}}",
"appointmentDateTime": "2026-06-03T11:00:00-0700",
"dealerDepartmentUUID": "{{department_uuid}}",
"source": "WEB",
"pickupTripInformation": {
"eventUUID": "{{pickup_trip_uuid}}",
"rideType": "PICKUP_VEHICLE",
"mustStartBy": "2026-06-03T10:30:00-0700"
},
"dropTripInformation": {
"eventUUID": "{{dropoff_trip_uuid}}",
"rideType": "DROPOFF_VEHICLE",
"rideTime": "2026-06-06T16:00:00-0700",
"mustStartBy": "2026-06-06T15:45:00-0700"
},
"appointmentInformation": {
"customerAppointmentPreference": {
"emailConfirmation": true,
"textConfirmation": true
}
}
}
Dropoff-only update
Use this when the appointment already has a mapped pickup and only the dropoff is changing.
{
"customerUUID": "{{customer_uuid}}",
"appointmentDateTime": "2026-06-03T11:00:00-0700",
"dealerDepartmentUUID": "{{department_uuid}}",
"source": "WEB",
"dropTripInformation": {
"eventUUID": "{{dropoff_trip_uuid}}",
"rideType": "DROPOFF_VEHICLE",
"rideTime": "2026-06-06T16:00:00-0700",
"mustStartBy": "2026-06-06T15:45:00-0700"
},
"appointmentInformation": {
"customerAppointmentPreference": {
"emailConfirmation": true,
"textConfirmation": true
}
}
}
Dropoff-only create
Use this when the appointment already has a mapped pickup and you want to add a linked dropoff.
{
"customerUUID": "{{customer_uuid}}",
"appointmentDateTime": "2026-06-03T11:00:00-0700",
"dealerDepartmentUUID": "{{department_uuid}}",
"source": "WEB",
"dropTripInformation": {
"rideType": "DROPOFF_VEHICLE",
"rideTime": "2026-06-06T15:00:00-0700",
"mustStartBy": "2026-06-06T14:45:00-0700"
},
"appointmentInformation": {
"customerAppointmentPreference": {
"emailConfirmation": true,
"textConfirmation": true
}
}
}
Create pickup and create dropoff
Use this when the appointment has no mapped pickup yet and you want to create both a new pickup and a linked dropoff in a single call. Neither side sends an eventUUID.
{
"customerUUID": "{{customer_uuid}}",
"appointmentDateTime": "2026-06-03T11:00:00-0700",
"dealerDepartmentUUID": "{{department_uuid}}",
"source": "WEB",
"pickupTripInformation": {
"rideType": "PICKUP_VEHICLE",
"mustStartBy": "2026-06-03T10:30:00-0700",
"originAddress": "123 Customer Street, Long Beach, CA"
},
"dropTripInformation": {
"rideType": "DROPOFF_VEHICLE",
"rideTime": "2026-06-06T15:00:00-0700",
"mustStartBy": "2026-06-06T14:45:00-0700"
},
"appointmentInformation": {
"customerAppointmentPreference": {
"emailConfirmation": true,
"textConfirmation": true
}
}
}
Delete dropoff only
Send dropTripInformation with only eventUUID.
{
"customerUUID": "{{customer_uuid}}",
"appointmentDateTime": "2026-06-03T11:00:00-0700",
"dealerDepartmentUUID": "{{department_uuid}}",
"source": "WEB",
"dropTripInformation": {
"eventUUID": "{{dropoff_trip_uuid}}"
},
"appointmentInformation": {
"customerAppointmentPreference": {
"emailConfirmation": true,
"textConfirmation": true
}
}
}
Delete pickup and linked dropoff
Send pickupTripInformation with only the pickup eventUUID. The linked dropoff, if present, is deleted automatically.
{
"customerUUID": "{{customer_uuid}}",
"appointmentDateTime": "2026-06-03T11:00:00-0700",
"dealerDepartmentUUID": "{{department_uuid}}",
"source": "WEB",
"pickupTripInformation": {
"eventUUID": "{{pickup_trip_uuid}}"
},
"appointmentInformation": {
"customerAppointmentPreference": {
"emailConfirmation": true,
"textConfirmation": true
}
}
}
Curl Example
curl --location --request PUT 'https://api.mykaarma.com/appointment/v2/dealers/{{dealer_uuid}}/partner-appointments-with-trip/{{sar_uuid}}' \
--header 'Authorization: Basic {{basic_auth_token}}' \
--header 'Content-Type: application/json' \
--data-raw '{
"customerUUID": "{{customer_uuid}}",
"appointmentDateTime": "2026-06-03T11:00:00-0700",
"dealerDepartmentUUID": "{{department_uuid}}",
"source": "WEB",
"pickupTripInformation": {
"eventUUID": "{{pickup_trip_uuid}}",
"rideType": "PICKUP_VEHICLE",
"mustStartBy": "2026-06-03T10:30:00-0700"
},
"dropTripInformation": {
"rideType": "DROPOFF_VEHICLE",
"rideTime": "2026-06-06T15:00:00-0700",
"mustStartBy": "2026-06-06T14:45:00-0700"
},
"appointmentInformation": {
"customerAppointmentPreference": {
"emailConfirmation": true,
"textConfirmation": true
},
"comments": "",
"internalNotes": "",
"recall": false
}
}'
Response
The response is a SaveAppointmentWithTripResponse object:
| Property Name | Value | Description |
|---|---|---|
eventUUID | String | UUID of the pickup trip affected by the request |
pickupEventUUID | String | Alias for eventUUID, returned for newer partner integrations |
dropoffEventUUID | String | UUID of the dropoff trip affected by the request, when applicable |
appointmentUUID | String | UUID of the updated appointment |
statusCode | Integer | HTTP status code of the response |
errors | List<Object> | List of errors, if any |
warnings | List<Object> | List of warnings, if any |
Response Example
{
"eventUUID": "{{pickup_trip_uuid}}",
"pickupEventUUID": "{{pickup_trip_uuid}}",
"dropoffEventUUID": "{{dropoff_trip_uuid}}",
"appointmentUUID": "{{appointment_uuid}}",
"statusCode": 200,
"errors": null,
"warnings": null
}
Possible Errors
The update API can fail at the authentication layer, the partner request validation layer, the trip-operation validation layer, or the downstream pickup/delivery and appointment-update layers.
Authentication and authorization errors
| HTTP Status | Error Code | When it happens |
|---|---|---|
401 | UNAUTHORIZED | The Basic Auth credentials are missing or invalid. |
403 | FORBIDDEN | The client does not have the required appointment.create scope at the dealer level for the requested dealer. |
Partner request validation errors
These are the explicit validation errors enforced by the partner update endpoint before the downstream update flow runs.
| HTTP Status | Error Code | Error Description | When it happens |
|---|---|---|---|
400 | INVALID_DEALER_UUID | Invalid dealer UUID is provided in the request | dealerUuid path param is blank or invalid. |
400 | INVALID_DEPT_UUID | Invalid dealer department UUID is provided in the request | dealerDepartmentUUID is missing from the request body. |
400 | CUSTOMER_INFO_MISSING | minimum info required to match customer: (FirstName OR LastName) AND At least any one Customer Communication (phone/email) OR (FirstName AND LastName) OR VIN(FirstName OR LastName) | customerUUID is missing from the partner request. |
400 | PARTNER_APPOINTMENT_DATETIME_REQUIRED | appointmentDateTime is required in the partner appointment request | appointmentDateTime is missing. |
400 | INVALID_APPOINTMENT_INFORMATION | Invalid request. appointmentInformation is blank. | appointmentInformation is missing. |
400 | PICKUP_AND_DELIVERY_TRANSPORT_OPTION_REQUIRED | Pickup and Delivery transport option is required when pickupTripInformation or dropTripInformation is present | appointmentInformation.transportOption is present but not set to PICKUP_AND_DELIVERY. |
400 | PICKUP_RIDE_TYPE_MUST_BE_PICKUP_VEHICLE | Pickup trip rideType must be PICKUP_VEHICLE | pickupTripInformation.rideType is sent with any non-pickup ride type. |
400 | DROPOFF_RIDE_TYPE_MUST_BE_DROPOFF_VEHICLE | Dropoff trip rideType must be DROPOFF_VEHICLE | dropTripInformation.rideType is sent with any non-dropoff ride type. |
400 | DROPOFF_RIDE_TIME_REQUIRED | dropTripInformation.rideTime is required for dropoff ride types | dropTripInformation represents a dropoff create or update, but rideTime is missing. |
400 | VALID_CREATOR_USER_UUID_REQUIRED | appointmentInformation.creatorUser.uuid is required when source is not WEB | source is not WEB (or is null) and appointmentInformation.creatorUser.uuid is missing or blank. |
400 | LOANER_AND_DROP_CAR_CANNOT_BOTH_BE_TRUE | loanerVehicleRequired and isDropCar cannot both be true | An operational pickupTripInformation or dropTripInformation payload has both loanerVehicleRequired=true and isDropCar=true. |
400 | PRIMARY_AND_SECONDARY_DRIVER_CANNOT_BE_SAME | primaryDriverUUID and secondaryDriverUUID cannot be the same | An operational pickupTripInformation or dropTripInformation payload has the same UUID set for primaryDriverUUID and secondaryDriverUUID. |
Trip-operation validation errors
After partner request validation passes, the update flow validates whether the pickup and dropoff operation mix is legal for the current appointment.
| HTTP Status | Error Code | Error Description | When it happens |
|---|---|---|---|
400 | NO_OPERATION_SPECIFIED | At least one trip operation must be specified | Neither pickup nor dropoff create/update/delete data is present. Appointment-only updates are not supported by this endpoint. |
400 | TRIP_ALREADY_EXISTS | Trip already exists for given appointment | The request tries to create a new pickup trip for an appointment that already has a mapped pickup trip. |
400 | INVALID_DROPOFF_WITH_NEW_PICKUP | Cannot reference an existing dropoff trip when creating a new pickup trip | The request tries to create a new pickup while referencing an existing dropoff eventUUID. |
400 | DROPOFF_ALREADY_EXISTS | Dropoff trip already exists for given pickup trip | The request tries to create a new dropoff for a pickup that already has a linked dropoff trip. |
400 | PICKUP_TRIP_NOT_LINKED_TO_APPOINTMENT | Pickup trip is not linked to the given appointment | The supplied pickup eventUUID does not match the pickup trip currently mapped to the appointment. |
400 | DROPOFF_TRIP_NOT_LINKED_TO_APPOINTMENT | Dropoff trip is not linked to the given appointment | The supplied dropoff eventUUID is not linked to the appointment's mapped pickup trip. |
Downstream pickup, dropoff, and appointment-update errors
After the operation shape is validated, the endpoint may still fail while updating the pickup trip, creating/updating/deleting the linked dropoff trip, or updating the appointment itself.
| HTTP Status | Error Code | When it happens |
|---|---|---|
400 | USER_TOKEN_IS_BLANK | source is not WEB (or is null) and the top-level requesterUserUUID is missing. The downstream PnD service requires requesterUserUUID for non-WEB sources. Typically the partner endpoint also blocks the request upfront with VALID_CREATOR_USER_UUID_REQUIRED when appointmentInformation.creatorUser.uuid is missing — both identity fields must be sent for non-WEB updates. |
400 | MISSING_ASSIGNED_BY_DEALER_ASSOCIATE_UUID | source is not WEB and appointmentInformation.creatorUser.uuid is missing. The partner endpoint normally catches this upfront with VALID_CREATOR_USER_UUID_REQUIRED; this code surfaces only when the partner-gate check is bypassed. |
4xx or 5xx | downstream pickup/delivery service error code | The pickup/dropoff service rejects the request or fails during the requested create, update, or delete operation. |
4xx or 5xx | downstream appointment service error code | The appointment update succeeds through trip processing but fails when saving the appointment changes. |
500 | INTERNAL_ERROR or INTERNAL_SERVER_ERROR | An unexpected server-side failure occurs while processing the request. |
Error response example
{
"eventUUID": null,
"pickupEventUUID": null,
"dropoffEventUUID": null,
"appointmentUUID": null,
"statusCode": 400,
"errors": [
{
"errorCode": "NO_OPERATION_SPECIFIED",
"errorDescription": "At least one trip operation must be specified"
}
],
"warnings": null
}