CommonTape Modify API
The Modify API from CommonTape — 1 operation(s) for modify.
The Modify API from CommonTape — 1 operation(s) for modify.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/commontape-com:commontape-com-modify-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Commontape Com Modify API
version: 1.0.0
x-word-list-version: 6
description: 'Operations tagged Modify across 2 of this provider''s published API definitions: commontape-com-agent-api-openapi.json, commontape-com-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://commontape.com
tags:
- name: Modify
paths:
/api/v1/modify:
post:
summary: Change a booking
description: 'Commits a change to a booked job: first quote the job again with its transaction_id (the next version), then modify with that quote_token, optionally moving it to another window. The job stays booked; the old version, quote and price are kept. The answer, and every refusal, carries change: its kinds (capacity, commercial, eligibility, approval, non_commercial), what was checked again and the price from and to. A refused change leaves the booked job exactly as it was; a new time and a new price commit together or not at all. A job the business called off answers SUPPLIER_CANCELLED with recovery. Moving to a time that is too soon answers INSUFFICIENT_NOTICE with error.earliest (M-21); a job that keeps its time is never checked again against a later No. The owner is emailed once about a change they can see (a new time, price, home or request). Check the new quote''s price against your customer''s limit before you modify: a change is priced against the business''s current offering. A quote of another job, or an older quote of this one, answers MODIFICATION_CONFLICT or QUOTE_EXPIRED. Refused with NEEDS_OWNER_APPROVAL (next_actions cancel, search) when the new quote adds, drops or rewords something the owner must approve. Refused with PRICE_MISMATCH (next_actions cancel, search) when it leaves out a task the booked job asked for: send every booked task again in inputs.addons. Refused with PRICE_MISMATCH when it is for a different ZIP, drops the home (leaves out a fact of the home the booked job stated: its kind, size or a room count; new values are allowed; refused with next_actions cancel, search), or does not state exactly the day and hour conditions of the window (a job that stays in its window keeps the same-day or next-day condition it was booked with). Also refused with NEEDS_OWNER_APPROVAL (next_actions cancel, search; booking_authority in the error) when the new version would not book on its own and costs more than the booked one, or moves a job the owner said yes to into another window: the owner''s yes covered that version only.'
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- transaction_id
- quote_token
- idempotency_key
properties:
transaction_id:
type: string
format: uuid
quote_token:
type: string
maxLength: 8000
new_allocation_id:
type: string
format: uuid
idempotency_key:
type: string
minLength: 8
maxLength: 128
description: Unique per write request (a UUID). Retrying with the same key returns the original result.
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
required:
- transaction_id
- state
- change
properties:
transaction_id:
type: string
format: uuid
state:
type: string
enum:
- booked
description: 'One of ten states, each with one meaning. quote_incomplete: Not priced yet: the job needs more facts. needs says which. Nothing is held. Allowed: quote. quoted: An exact price for one exact job version, until expires_at. Nothing is held: the time is not reserved yet. Allowed: hold, quote. held: A time is reserved for this job until hold_expires_at. Book it, or cancel to let it go. Allowed: book, cancel. pending_approval: Asked to book; the owner must say yes by approval.deadline. The time stays reserved while waiting. No answer by then and the job expires and the time is released. Allowed: status, cancel. booked: The owner is committed to do this job at this price and time. Allowed: status, quote, modify, cancel. completed: The job was done. completion.source says who marked it: the owner (merchant) or CommonTape after the window ended (system). Allowed: status. declined: The owner said no. decline.reason says why; decline.next_available is the next open time when there is one. Allowed: status, quote. cancelled: Called off by the agent. The time was released. Allowed: status, quote. supplier_cancelled: Called off by the owner after it was booked. The job can be quoted again elsewhere from job. Allowed: status, quote. expired: Ran out of time: the quote passed expires_at, or the hold or the owner''s answer passed its deadline. The time was released. Allowed: status, quote.'
allowed_actions:
type: array
items:
type: string
enum:
- quote
- hold
- book
- modify
- cancel
- status
description: The operations you may call on this job now. Anything else is refused (INVALID_STATE, ALREADY_BOOKED, ALREADY_CANCELLED).
next_actions:
type: array
items:
type: string
enum:
- provide_missing_input
- quote
- hold
- book
- await_supplier_approval
- select_alternative_window
- search
- cancel
- status
- wait_for_job
- retry_later
- fix_request
- register
description: The suggested next steps, from a fixed list.
job_version:
type:
- integer
- 'null'
description: The job's version. Every change to the job is a new version; old versions, their quotes and prices are kept, never written over.
change:
type: object
description: 'What kind of change this was (a set): capacity (the time or the cleaners), commercial (the price or anything priced: extras, skips, conditions, the home), eligibility (the home or the conditions, judged again), approval (something the owner must say yes to; refused as NEEDS_OWNER_APPROVAL), non_commercial (none of these). rechecked: what was checked again (always approval, eligibility and commercial, since the job is quoted again; capacity when the time or cleaners change).'
properties:
kinds:
type: array
items:
type: string
enum:
- non_commercial
- commercial
- eligibility
- capacity
- approval
rechecked:
type: array
items:
type: string
enum:
- non_commercial
- commercial
- eligibility
- capacity
- approval
price:
type: object
properties:
from:
type: number
to:
type: number
currency:
type: string
from_version:
type:
- integer
- 'null'
to_version:
type:
- integer
- 'null'
refused:
type: string
enum:
- non_commercial
- commercial
- eligibility
- capacity
- approval
description: 'On a refusal: the kind whose check said no. The booked job is unchanged.'
default:
$ref: '#/components/responses/Error'
tags:
- Modify
operationId: postApiV1Modify
x-operation-id-source: derived
servers:
- url: https://commontape.com
components:
responses:
Error:
description: Error
content:
application/json:
schema:
type: object
properties:
error:
type: object
required:
- code
- message
- next_actions
properties:
code:
type: string
enum:
- OUTSIDE_AREA
- OUTSIDE_HOURS
- CAPACITY_FULL
- SERVICE_UNKNOWN
- PRICE_MISMATCH
- HOLD_EXPIRED
- OWNER_DECLINED
- OWNER_UNDID
- SLOT_TAKEN
- REV_STALE
- QUOTE_EXPIRED
- INVALID_STATE
- ALREADY_BOOKED
- ALREADY_CANCELLED
- MODIFICATION_CONFLICT
- PRICE_CHANGED
- HOLD_EXISTS
- BUSINESS_UNAVAILABLE
- NEEDS_OWNER_APPROVAL
- SUPPLIER_CANCELLED
- INSUFFICIENT_NOTICE
- CALENDAR_BUSY
- UNAUTHORIZED
- RATE_LIMITED
- INVALID_REQUEST
- NOT_FOUND
- IDEMPOTENCY_KEY_CONFLICT
- TEMPORARY_ERROR
description: 'Authoritative. The ten business codes (AGT-8); the transaction codes (QUOTE_EXPIRED: quote again; INVALID_STATE: not allowed in this state, read status; ALREADY_BOOKED; ALREADY_CANCELLED; MODIFICATION_CONFLICT: the job changed while you acted, or the quote is not this job''s; PRICE_CHANGED: the price moved since the quote, see price_changed and hold the new quote_token; HOLD_EXISTS: you already hold this job at this business, see transaction_id; NEEDS_OWNER_APPROVAL: a change of a booked job needs the owner''s yes, cancel and book new; SUPPLIER_CANCELLED: the business called off this job, search again with recovery.job; BUSINESS_UNAVAILABLE: the business stopped taking jobs or no longer does this one, see reasons and alternatives; CALENDAR_BUSY: the time is busy in the business''s own calendar feed, read right before the hold, see alternatives for the next free window); and the protocol codes.'
message:
type: string
description: Plain words for a person. The code is what to act on.
next_actions:
type: array
items:
type: string
enum:
- provide_missing_input
- quote
- hold
- book
- await_supplier_approval
- select_alternative_window
- search
- cancel
- status
- wait_for_job
- retry_later
- fix_request
- register
description: The suggested next steps, from a fixed list.
state:
type: string
enum:
- quote_incomplete
- quoted
- held
- pending_approval
- booked
- completed
- declined
- cancelled
- supplier_cancelled
- expired
description: The job's state, when the refusal is about it.
booking_authority:
type: object
description: 'When the refusal is about who may book (modify): the authority the change was judged under.'
required:
- mode
- reasons
- version
properties:
mode:
type: string
enum:
- auto
- approval_required
reasons:
type: array
items:
type: string
examples:
- owner_approves_every_job
- over_auto_book_limit
- business_not_listed
- special_request
- cond.very_dirty
version:
type: integer
description: The owner's booking setting's version (versions.booking_authority).
price_changed:
type: object
required:
- old_amount
- new_amount
- currency
- reasons
description: 'PRICE_CHANGED: the old and new amount and the lines that changed.'
properties:
old_amount:
type: number
new_amount:
type: number
currency:
type: string
reasons:
type: array
items:
type: string
description: The price lines that were added, removed or changed (breakdown keys such as base, bedrooms, cond.pets, minimum_adjustment), or price_rules_changed when the business changed how it prices.
quote_token:
type: string
description: 'PRICE_CHANGED: a token for the same job at the new price. Hold it as it is.'
transaction_id:
type: string
format: uuid
description: 'HOLD_EXISTS: your open hold of this same job at this business.'
retry_after_seconds:
type: integer
minimum: 1
description: 'RATE_LIMITED for holds you let run out: when the next hold is allowed again.'
reasons:
type: array
items:
type: object
properties:
code:
type: string
label:
type: string
description: 'BUSINESS_UNAVAILABLE: why the business can no longer do this job (not_taking_jobs, or a near-miss reason such as a must-have it no longer offers).'
alternatives:
type: array
maxItems: 6
description: 'Ready alternatives for the same job, worked out on every answer by the same judge as search: up to 3 other times at this business and up to 3 other businesses. An alternative never misses a must-have, never offers a must-not and never adds back a task the customer left out; a nice-to-have it misses is named in why. Each is priced for its own window (its day and hour charges): hold its quote_token with its allocation_id as it is.'
items:
type: object
required:
- kind
- slug
- display_name
- service_key
- allocation_id
- window_start
- window_end
- price
- quote_token
- expires_at
- why
properties:
kind:
type: string
enum:
- same_business_other_time
- other_business_same_job
slug:
type: string
display_name:
type: string
service_key:
type: string
allocation_id:
type: string
format: uuid
window_start:
type: string
format: date-time
window_end:
type: string
format: date-time
job_hours:
type:
- integer
- 'null'
minimum: 1
description: 'How long this job takes on site, in whole hours: hourly services the hours asked (rounded up); other services the booking length plus the business''s bigger-homes hours when the home meets its rule. For a business that builds its open times from its working hours (discover capacity.jobs_at_once), every offered time is exactly this long.'
job_people:
type:
- integer
- 'null'
minimum: 1
description: 'How many cleaners this job takes: an hourly price''s people, the business''s usual crew (crew.min), more when the home meets its crew rule (crew.rule), at least 2 for a must-not crew.solo or must-have crew.two_or_more, 3 for crew.three_or_more. Counted against capacity.cleaners. null while the quote is incomplete.'
price:
type: object
properties:
amount:
type: number
currency:
type: string
quote_token:
type: string
expires_at:
type: string
format: date-time
booking_authority:
type:
- object
- 'null'
why:
type: array
items:
type: string
description: 'Fixed codes: other_time, other_business, nice_to_have_missed:<word>, needs_owner_approval.'
alternatives_note:
type: string
enum:
- timed_out
- none_found
description: 'Why alternatives is empty: none fit every must, or they could not be worked out within 4 seconds (the refusal is never delayed for them).'
if_changed:
type: array
maxItems: 2
description: 'Businesses that could do this job if the customer gave up ONE thing (up to 2). None of them can be held or booked from this item: it carries no quote_token and no allocation_id. Ask the customer; if they agree, search again without change.word (that is a new job). A must-have the business said it does not offer, or a must-not that is its only option, is the only kind of change listed; never something the business has not answered, what it takes (the home), a condition of the home, or a second change. You can still quote such a business by name, but do not book it with the job unchanged without the customer''s yes.'
items:
type: object
required:
- slug
- display_name
- service_key
- change
- price_if_changed
- earliest_window_start
- nice_to_have_missed
- needs_owner_approval
- next_step
properties:
slug:
type: string
display_name:
type: string
service_key:
type: string
change:
type: object
description: 'The one thing the customer would give up: a word out of must_have or out of must_not, with the business''s own reason.'
properties:
from:
type: string
enum:
- must_have
- must_not
word:
type: string
code:
type: string
label:
type: string
price_if_changed:
type: object
properties:
amount:
type: number
currency:
type: string
description: 'The changed job''s search price at this business: the same number a search without change.word shows. Not the price at earliest_window_start when the business charges for days or hours.'
earliest_window_start:
type:
- string
- 'null'
format: date-time
nice_to_have_missed:
type: array
items:
type: string
needs_owner_approval:
type: boolean
description: The changed job would wait for the owner's yes there.
next_step:
type: string
enum:
- ask_customer_then_search
if_changed_note:
type: string
enum:
- timed_out
- none_found
description: 'Why if_changed is empty: no business is one change away, or they could not be worked out within the 4 seconds (the ready alternatives are kept).'
change:
type: object
description: 'modify refusals: the change it would have been, with refused (the kind whose check said no). The booked job is unchanged.'
properties:
kinds:
type: array
items:
type: string
enum:
- non_commercial
- commercial
- eligibility
- capacity
- approval
rechecked:
type: array
items:
type: string
enum:
- non_commercial
- commercial
- eligibility
- capacity
- approval
price:
type: object
properties:
from:
type: number
to:
type: number
currency:
type: string
from_version:
type:
- integer
- 'null'
to_version:
type:
- integer
- 'null'
refused:
type: string
enum:
- non_commercial
- commercial
- eligibility
- capacity
- approval
description: 'On a refusal: the kind whose check said no. The booked job is unchanged.'
recovery:
type: object
description: 'SUPPLIER_CANCELLED, and ALREADY_CANCELLED on a job the business called off: the job to search again with.'
properties:
job:
type: object
alternatives:
type: array
maxItems: 6
description: 'Ready alternatives for the same job, worked out on every answer by the same judge as search: up to 3 other times at this business and up to 3 other businesses. An alternative never misses a must-have, never offers a must-not and never adds back a task the customer left out; a nice-to-have it misses is named in why. Each is priced for its own window (its day and hour charges): hold its quote_token with its allocation_id as it is.'
items:
type: object
required:
- kind
- slug
- display_name
- service_key
- allocation_id
- window_start
- window_end
- price
- quote_token
- expires_at
- why
properties:
kind:
type: string
enum:
- same_business_other_time
- other_business_same_job
slug:
type: string
display_name:
type: string
service_key:
type: string
allocation_id:
type: string
format: uuid
window_start:
type: string
format: date-time
window_end:
type: string
format: date-time
job_hours:
type:
- integer
- 'null'
minimum: 1
description: 'How long this job takes on site, in whole hours: hourly services the hours asked (rounded up); other services the booking length plus the business''s bigger-homes hours when the home meets its rule. For a business that builds its open times from its working hours (discover capacity.jobs_at_once), every offered time is exactly this long.'
job_people:
type:
- integer
- 'null'
minimum: 1
description: 'How many cleaners this job takes: an hourly price''s people, the business''s usual crew (crew.min), more when the home meets its crew rule (crew.rule), at least 2 for a must-not crew.solo or must-have crew.two_or_more, 3 for crew.three_or_more. Counted against capacity.cleaners. null while the quote is incomplete.'
price:
type: object
properties:
amount:
type: number
currency:
type: string
quote_token:
type: string
expires_at:
type: string
format: date-time
booking_authority:
type:
- object
- 'null'
why:
type: array
items:
type: string
description: 'Fixed codes: other_time, other_business, nice_to_have_missed:<word>, needs_owner_approval.'
alternatives_note:
type: string
enum:
- timed_out
- none_found
description: 'Why alternatives is empty: none fit every must, or they could not be worked out within 4 seconds (the refusal is never delayed for them).'
next_step:
type: string
enum:
- search_again_with_job
earliest:
type: string
format: date-time
description: 'INSUFFICIENT_NOTICE (M-21): no start before this is taken (RFC 3339, business offset): the later of the notice cutoff and the first calendar day the same-day / next-day No allows. A later time may still be closed (weekends, holidays, working hours): pick from available_windows.'
reason:
type: string
enum:
- scope_not_confirmed
description: 'SERVICE_UNKNOWN on a direct quote (M-21): the owner has not confirmed what this service includes (discover matchable false).'
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: Your agent key (ct_live_...). Get one with POST /api/v1/keys (no key needed); the demo key ct_demo_... needs no registration.
x-refined-from:
- commontape-com-agent-api-openapi.json
- commontape-com-openapi.yml