For partners and their developers

Partner guide

Put Talkspresso booking, payment and video inside your own platform, with your name on it.

This guide is for two people. If you run the business, read sections 1, 2, 5, 6 and 8. If you build the integration, read all of it. Sections 3, 4, 7 and 9 are written for you. Every call and answer shown was run against our staging system. Nothing here describes something we have not built.

Looking for the API for your own account or organization, which you use with a key? See the API reference.

1. What you get

You keep your platform and your members. Talkspresso handles booking, payment and video, which are hard to build well.

What a partner gets
Your coaches, listed on your platformYour members see your coaches and their sessions on your own platform, with your name and look. Buyers do not need a Talkspresso account.
Booking and payment handledTalkspresso checks the coach’s calendar, takes the booking and collects the payment. Your server books free sessions directly. For paid sessions, Talkspresso opens its own payment page and sends the buyer back to you after they pay.
The video callEach booking comes with a video room. Buyers join from a link you give them. You can also show the room inside your own page (see “Show the room in your page”).
Booking emails your wayYou choose who sends the buyer’s booking emails: Talkspresso, Talkspresso with your name and logo, or your own platform (see “Booking emails”).
Updates when a booking changesWebhooks (messages we send to your server) tell it when a booking is created, paid, moved, cancelled or completed, so your server does not have to keep asking.
How money worksEach coach is paid directly into the coach’s own PayPal account. Talkspresso’s fee on bookings from your platform is set in your agreement. Talkspresso does not pay you a share through the platform. Any arrangement between you and your coaches is yours.
A test system to build on firstYou build and test on a staging copy (our test system) with a sandbox key and PayPal’s sandbox. No real money moves.

2. How it starts

Six steps, in this order. Section 8 has the checklist that decides when you go live.

  1. Together

    We agree the terms. The agreement has a schedule that lists your settings and Talkspresso’s fee. Plans are named Community, Platform and Enterprise. Your agreement says which one applies and what it covers.

  2. Talkspresso

    We create your organization on Talkspresso with your name, logo, colors and contact email. Once the agreement is signed we set the settings that only Talkspresso can change (see “Settings you control and settings Talkspresso sets”).

  3. You and your coaches

    You invite your coaches. Each coach agrees to be listed on your platform and to let you cancel or move their sessions. A coach who sells paid sessions connects a PayPal account. A coach who is new to Talkspresso may have to wait a short time before buyers can book their paid sessions.

  4. Talkspresso

    We give you a sandbox key for staging. It works for 14 days and only on staging. We also register the addresses your build needs: the web address buyers return to after paying, the website that will show the video room, and your webhook address.

  5. Your developers

    You build and test against staging. The go-live checklist (section 8) shows what is done and what is left. GET /settings returns the current checklist at any time.

  6. Talkspresso

    We run one paid test booking, then refund it, using your final settings and fee. When every item on the checklist is done, we create a production key and give it to you by a method other than email.

3. Flows and calls

Each flow lists who does what, then shows the real call. Every call on this page runs against staging with a sandbox key. Run them in order. The examples use ids from our own test organization. The dates in them will be in the past when you read this: take a start_time from a fresh availability answer, within the next 14 days.

How every call works

Basics of the partner API
Base addressStaging: https://api-staging.talkspresso.com/partner/v1. Production: https://api.talkspresso.com/partner/v1 (production keys come after go-live).
Your keySend Authorization: Bearer tsp_... on every call. Keep it on your server. One key belongs to one organization and cannot access any other organization’s data. It can read and write bookings; it cannot create keys or change settings.
Scopespartner:read lets you read. partner:bookings lets you create, cancel and move bookings. partner:webhooks lets you ask for an event to be sent again. Your key has all three.
Idempotency-KeyRequired on every POST except replay. Use a new value for each action. If you retry the same action, send the same value. 8 to 255 characters: letters, digits and _ . : -. The same key with the same body returns the first answer and adds the header Idempotent-Replayed: true. The same key with a different body is refused with 422. We remember each key for 24 hours.
TimesStart times are ISO 8601 with a zone, for example 2026-11-17T16:00:00Z. Answers are in UTC. A time with no zone is refused.
partner_refYour own order or user reference, up to 128 characters. It comes back on the booking, in webhooks and in GET /bookings?partner_ref=.
MoneyAmounts are whole US cents (paid_cents) and the currency is always USD.
Set up your shell
export TSP_KEY="tsp_your_sandbox_key"
API=https://api-staging.talkspresso.com/partner/v1

Errors

Every error has this shape: { "error": { "code", "message" } }. Some errors also include fields or retry_after_seconds. In your code, use code, not the message text.

Errors the partner API returns
400validation_failedA field is missing or wrong. fields lists them.
400idempotency_key_requiredAdd an Idempotency-Key header (also idempotency_key_invalid for a bad value).
401invalid_credentialsNo key, a wrong key, an expired key or a revoked key.
402payment_requiredThe session is paid. Use POST /checkouts instead of POST /bookings.
403missing_scopeThe key does not hold the scope this call needs.
403org_not_readyYour organization is not ready to use the partner API. Email support@talkspresso.com.
404not_foundThe id does not exist, belongs to another organization, or was not created by your platform.
409slot_unavailableSomeone took that time or the coach no longer offers it. Ask for availability again.
409coach_consent_requiredThis coach has not agreed that you may cancel or move their sessions.
409notifications_mode_not_enabledYou asked for booking emails your organization is not set up for. See “Booking emails”.
409webhook_endpoint_requiredYou asked for notifications “partner” but you have no webhook endpoint that receives booking.created.
409request_in_progressA call with the same Idempotency-Key is still being processed. Wait a moment and retry.
422idempotency_key_reusedThe same Idempotency-Key was used with a different body.
422return_url_not_allowedThe return address must be https on a host we registered for you.
422booking_terms_need_buyer_consentThis coach has booking terms the buyer must accept on the payment page. Use a checkout.
429rate_limitedToo many calls. retry_after_seconds says how long to wait.
Example: no key, 401
{
  "error": {
    "code": "invalid_credentials",
    "message": "Invalid or missing API key."
  }
}

Limits

If you go over a limit, you get 429 with retry_after_seconds. Wait that many seconds before you call again.

Request limits
Reads120 a minute per key
Writes30 a minute per key
Bookings and checkouts opened300 a day per key, for at most 150 different buyers a day
Checkouts for one buyer email5 a minute
Cancels and moves20 an hour each
Room links60 an hour
Replays of one event5 an hour
A new keyFor its first 24 hours, every limit above is one quarter of the number shown. Plan your first load test for day two.

Show your coaches and their times

  1. Your server

    GET /providers. You get your coaches and the sessions each one offers, with duration and price in cents. You can keep the answer for a few minutes, then ask again.

  2. Your page

    Show your coaches and their sessions. A coach with price_cents 0 offers a free session.

  3. Your server

    GET /services/:id/intake-questions. Use it when the coach asks the buyer questions before the session. Show the questions in your form and send the answers with the booking.

  4. Your server

    GET /services/:id/availability for the dates the buyer is looking at (up to 14 days at a time, in the buyer’s time zone). The times are always current, so you are never offered a time that was just taken.

List providers
curl -s "$API/providers" \
  -H "Authorization: Bearer $TSP_KEY"
Response 200 (one coach shown)
{
  "data": [
    {
      "id": "sn_andre",
      "name": "Andre Williams",
      "title": "Leadership Coach & Former Founder",
      "handle": "andre-williams",
      "photo_url": "/images/startupnash/andre.jpg",
      "headline": "",
      "services": [
        {
          "id": "svc_sn_andre_williams_mentor",
          "title": "1:1 Mentorship Session",
          "duration_minutes": 30,
          "price_cents": 0,
          "currency": "USD",
          "free": true
        }
      ]
    }
  ]
}
Availability for two days
curl -s "$API/services/svc_sn_andre_williams_mentor/availability?from=2026-11-17&days=2&timezone=America/Chicago" \
  -H "Authorization: Bearer $TSP_KEY"
Response 200 (two times shown)
{
  "data": {
    "service_id": "svc_sn_andre_williams_mentor",
    "provider_id": "sn_andre",
    "timezone": "America/Chicago",
    "duration_minutes": 30,
    "slots": [
      {
        "start_time": "2026-11-17T15:00:00.000Z",
        "end_time": "2026-11-17T15:30:00.000Z"
      },
      {
        "start_time": "2026-11-17T15:30:00.000Z",
        "end_time": "2026-11-17T16:00:00.000Z"
      }
    ]
  }
}

Book a free session

  1. Buyer

    Picks a time and gives you a name and an email.

  2. Your server

    POST /bookings with a new Idempotency-Key. The answer is 201 with the booking and the buyer’s join link.

  3. Talkspresso

    Books the time, emails the buyer and the coach, and sends booking.created to your webhook.

  4. Your page

    Shows “you are booked”, and shows the join link when it is time to join. If a call fails or times out, send the same request again with the same Idempotency-Key. You will not get two bookings.

Create a free booking
curl -s -X POST "$API/bookings" \
  -H "Authorization: Bearer $TSP_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-booking" \
  -d '{
    "provider_id": "sn_andre",
    "service_id": "svc_sn_andre_williams_mentor",
    "start_time": "2026-11-17T16:00:00Z",
    "buyer": { "name": "Sam Rivera", "email": "sam@example.com", "timezone": "America/Chicago" },
    "partner_ref": "order-1042"
  }'
Response 201
{
  "data": {
    "id": "cmwecj3ax00dm1vjzdl3ceij7",
    "status": "active",
    "approval_status": "auto_approved",
    "start_time": "2026-11-17T16:00:00.000Z",
    "end_time": "2026-11-17T16:30:00.000Z",
    "duration_minutes": 30,
    "provider": {
      "id": "sn_andre",
      "name": "Andre Williams"
    },
    "service": {
      "id": "svc_sn_andre_williams_mentor",
      "title": "1:1 Mentorship Session"
    },
    "buyer": {
      "name": "Sam Rivera",
      "email": "sam@example.com"
    },
    "partner_ref": "order-s5-1794536217",
    "paid_cents": 0,
    "currency": "USD",
    "created_at": "2026-11-13T02:16:57.466Z",
    "join_url": "https://staging.talkspresso.com/meet/SESSION_ID?cid=BUYER_ID&ct=BUYER_TOKEN",
    "notes_available": false
  }
}

join_url is the buyer’s link to the call. Treat it like a password: share it only with that buyer. A paid session answers this call with 402 payment_required. If a field is missing, you get 400, and fields lists the field names.

Same Idempotency-Key, different body: 422
{
  "error": {
    "code": "idempotency_key_reused",
    "message": "This Idempotency-Key was already used with a different request."
  }
}
Two people want the same time: the second gets 409
{
  "error": {
    "code": "slot_unavailable",
    "message": "That time is no longer available.",
    "reason": "slot_taken"
  }
}

Book and pay

  1. Buyer

    Picks a time on a paid session and gives you a name and an email.

  2. Your server

    POST /checkouts with the same body as a booking, plus return_url (an https address on a host we registered). The answer is 201 with a checkout and a url. It is open for 30 minutes.

  3. Your page

    Send the buyer to url exactly as given. Do not log or store it. The part after # lets one buyer pay for this booking.

  4. Buyer

    Pays on the Talkspresso payment page, with PayPal or a card. The page shows the coach, the price, the cancellation rule and your organization’s name and logo.

  5. Talkspresso

    Sends the buyer back to your return_url with ?checkout_id=...&status=paid added. Talkspresso also sends checkout.paid and booking.paid to your webhook.

  6. Your server

    Do not trust status in the address, because the buyer can edit it. Confirm with GET /checkouts/:id (status paid, booking_id set) or wait for the webhook. The webhook arrives even if the buyer closes the tab before returning. A checkout that is not paid in 30 minutes becomes expired.

  7. Your server

    GET /bookings/:id for the booking and the join link.

Open a checkout
curl -s -X POST "$API/checkouts" \
  -H "Authorization: Bearer $TSP_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1043-checkout" \
  -d '{
    "provider_id": "cmlrh3wdm002l1qhg56q14ydj",
    "service_id": "svc-ppcp-walkthrough-50",
    "start_time": "2026-11-17T15:30:00Z",
    "buyer": { "name": "Sam Rivera", "email": "sam@example.com" },
    "partner_ref": "order-1043",
    "return_url": "https://partner-e2e.example.com/done"
  }'
Response 201
{
  "data": {
    "id": "cmweclzhd00gf1vjz7ucke94j",
    "status": "open",
    "url": "https://staging.talkspresso.com/pay/partner/cmweclzhd00gf1vjz7ucke94j#token=CHECKOUT_TOKEN",
    "expires_at": "2026-11-13T02:49:12.480Z",
    "partner_ref": "order-s5-1794536217-co",
    "booking_id": null,
    "provider_id": "cmlrh3wdm002l1qhg56q14ydj",
    "service_id": "svc-ppcp-walkthrough-50",
    "start_time": "2026-11-17T15:30:00.000Z"
  }
}
Check a checkout
curl -s "$API/checkouts/CHECKOUT_ID" \
  -H "Authorization: Bearer $TSP_KEY"
Response 200 (open until the buyer pays)
{
  "data": {
    "id": "cmweclzhd00gf1vjz7ucke94j",
    "status": "open",
    "expires_at": "2026-11-13T02:49:12.480Z",
    "partner_ref": "order-s5-1794536217-co",
    "booking_id": null,
    "provider_id": "cmlrh3wdm002l1qhg56q14ydj",
    "service_id": "svc-ppcp-walkthrough-50",
    "start_time": "2026-11-17T15:30:00.000Z"
  }
}

A checkout has one of four statuses: open, paid, expired or cancelled. Once it is paid, booking_id has a value. The return address must be https on a host we registered for you. Any other address is refused:

Wrong return host: 422
{
  "error": {
    "code": "return_url_not_allowed",
    "message": "return_url must be https on a host registered for this organization.",
    "fields": [
      "return_url"
    ]
  }
}
A paid session sent to POST /bookings: 402
{
  "error": {
    "code": "payment_required",
    "message": "This service is paid. Open a checkout with POST /partner/v1/checkouts.",
    "next": "POST /partner/v1/checkouts"
  }
}

Buyers pay on a Talkspresso payment page

The payment page shows your organization’s name and logo at the top. It always shows the coach as the seller, the price, the cancellation rule and a line saying Talkspresso collects the payment through PayPal.

Look up bookings

GET /bookings/:id returns one booking with its join link. GET /bookings lists your bookings, without join links. Filter with partner_ref, status (active, cancelled, awaiting_payment, completed), provider_id, from and to. Get more results with cursor and limit (1 to 100). GET /bookings/:id/intake returns the buyer’s answers to the coach’s questions.

Read one booking
curl -s "$API/bookings/BOOKING_ID" \
  -H "Authorization: Bearer $TSP_KEY"

Cancel and refund

  1. Your server

    POST /bookings/:id/cancel with a new Idempotency-Key and a reason_code. The reason_code is required.

  2. Talkspresso

    Cancels, refunds the buyer in full to the original payment method with no late fee, emails the buyer with your organization’s name and the reason in plain words, and tells the coach.

  3. Your server

    You get the cancelled booking back. booking.cancelled goes to your webhook with cancelled_by set to partner.

Cancel reason codes
buyer_requestedThe buyer asked you to cancel. The buyer’s email says “at your request”.
partner_causeA reason on your side. The email says “because of a reason on your side”.
duplicateThe session was booked twice.
fraud_suspectedYou suspect a problem with the payment.
Cancel a booking
curl -s -X POST "$API/bookings/BOOKING_ID/cancel" \
  -H "Authorization: Bearer $TSP_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-cancel" \
  -d '{ "reason_code": "buyer_requested" }'
Response 200
{
  "data": {
    "id": "cmwecj3ax00dm1vjzdl3ceij7",
    "status": "cancelled",
    "approval_status": "auto_approved",
    "start_time": "2026-11-17T19:00:00.000Z",
    "end_time": "2026-11-17T19:30:00.000Z",
    "duration_minutes": 30,
    "provider": {
      "id": "sn_andre",
      "name": "Andre Williams"
    },
    "service": {
      "id": "svc_sn_andre_williams_mentor",
      "title": "1:1 Mentorship Session"
    },
    "buyer": {
      "name": "Sam Rivera",
      "email": "sam@example.com"
    },
    "partner_ref": "order-s5-1794536217",
    "paid_cents": 0,
    "currency": "USD",
    "created_at": "2026-11-13T02:16:57.466Z",
    "notes_available": false
  }
}
No reason_code: 400
{
  "error": {
    "code": "validation_failed",
    "message": "The request body is not valid.",
    "fields": [
      "reason_code"
    ]
  }
}

A coach must have agreed that you may cancel their sessions. If not, the call returns 409 coach_consent_required and nothing is refunded. The buyer can still cancel from the manage link Talkspresso emails them (in partner mode they get one only if Talkspresso sent a confirmation or they ask for a new link), or you can ask the coach.

Move a booking

  1. Your server

    GET /services/:id/availability for new times.

  2. Your server

    POST /bookings/:id/reschedule with a new Idempotency-Key and { "start_time": "..." }.

  3. Talkspresso

    Moves the booking if the coach allows it. A coach can limit how many times a buyer can move a booking and how close to the start time a move can happen. If the move has a reschedule fee, only the buyer can pay it, from the manage link Talkspresso emails them. Your call then gets 409 reschedule_fee_required.

  4. Your server

    You get the booking back with the new time. booking.rescheduled goes to your webhook.

Move a booking
curl -s -X POST "$API/bookings/BOOKING_ID/reschedule" \
  -H "Authorization: Bearer $TSP_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-move" \
  -d '{ "start_time": "2026-11-17T19:00:00Z" }'
Response 200
{
  "data": {
    "id": "cmwecj3ax00dm1vjzdl3ceij7",
    "status": "active",
    "approval_status": "auto_approved",
    "start_time": "2026-11-17T19:00:00.000Z",
    "end_time": "2026-11-17T19:30:00.000Z",
    "duration_minutes": 30,
    "provider": {
      "id": "sn_andre",
      "name": "Andre Williams"
    },
    "service": {
      "id": "svc_sn_andre_williams_mentor",
      "title": "1:1 Mentorship Session"
    },
    "buyer": {
      "name": "Sam Rivera",
      "email": "sam@example.com"
    },
    "partner_ref": "order-s5-1794536217",
    "paid_cents": 0,
    "currency": "USD",
    "created_at": "2026-11-13T02:16:57.466Z",
    "notes_available": false
  }
}

Booking emails

Your organization has a setting called “Who sends booking emails”. An owner or admin changes it in Partner settings, or you email us. A key cannot change it. It has three values:

Who sends booking emails
talkspressoTalkspresso sends every booking email, plain, with no organization name.
brandedTalkspresso sends every booking email. On bookings your platform creates, the emails carry your organization’s name and logo, and the sender reads “Your organization via Talkspresso” (the organization part is cut to 24 characters). Replies go to your organization’s support email when one is set.
partnerYour platform sends the buyer’s confirmation and reminders, and any thank-you it wants to send. Talkspresso sends only the emails listed under “Always sent by Talkspresso”.

You can also ask for a value on one booking. Add notifications to POST /bookings or POST /checkouts, with talkspresso, branded or partner. If you leave it out, the organization’s setting applies. A request can ask for less than the setting, never more. The booking answer does not repeat the value.

Ask for branded emails on one booking (201, same answer as above)
curl -s -X POST "$API/bookings" \
  -H "Authorization: Bearer $TSP_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1044-booking" \
  -d '{
    "provider_id": "sn_andre",
    "service_id": "svc_sn_andre_williams_mentor",
    "start_time": "2026-11-18T16:00:00Z",
    "buyer": { "name": "Sam Rivera", "email": "sam@example.com" },
    "partner_ref": "order-1044",
    "notifications": "branded"
  }'
Your organization is not set to partner: 409
{
  "error": {
    "code": "notifications_mode_not_enabled",
    "message": "Your organization is not set up for \"partner\" booking emails. Change \"Who sends booking emails\" in your organization's partner settings first.",
    "fields": ["notifications"]
  }
}
Set to partner but no endpoint receives booking.created: 409
{
  "error": {
    "code": "webhook_endpoint_required",
    "message": "\"partner\" booking emails need an active webhook endpoint subscribed to booking.created, so your platform is told to send the buyer's email.",
    "fields": ["notifications"]
  }
}

Any other value is refused with 400 validation_failed and fields set to ["notifications"].

What changes when your platform sends the emails:

  • Partner mode needs a live webhook endpoint that receives booking.created. Without one, a request for partner is refused with 409 webhook_endpoint_required. If your endpoint is paused or removed later, Talkspresso goes back to sending the emails itself.
  • Send the confirmation after you receive booking.created. “Delivered” means your endpoint answered with an HTTP 2xx. It does not mean your mailer sent anything.
  • Talkspresso sends no reminders for these bookings, and there is no reminder event. Use the start_time in booking.created to schedule your own.
  • The coach’s calendar invitation is not emailed to the buyer in partner mode either, while your endpoint is live.
  • If booking.created is not delivered and answered with 2xx within 30 minutes (the check runs every 5 minutes, so allow up to 35), Talkspresso sends the buyer’s confirmation itself. If your endpoint answers late, the buyer can get both emails. The buyer always gets one confirmation.
  • A confirmation is never held back when the session starts within 60 minutes. Talkspresso sends it at once. After Talkspresso has sent a booking’s confirmation in this way, it sends that booking’s reminders too.
  • If your organization is set back to talkspresso or branded, Talkspresso sends the emails for every booking from then on, including bookings made earlier.

Always sent by Talkspresso

In every mode, Talkspresso never holds back an email that carries money, a cancellation, a link the buyer asked for or a notice about recording. In partner mode these emails also read “Your organization via Talkspresso”, with your organization’s name and logo, so the buyer knows who they are from.

Emails Talkspresso always sends
CancellationsThe buyer is told when a booking is cancelled, by anyone. A cancel you make through the API sends one notice with your organization’s name, who cancelled, the reason in plain words and the refund.
RefundsAny email about money going back to the buyer.
Moves and feesA booking moved to a new time, and any reschedule fee charged, kept or returned.
Booking approvalA coach approved or declined a booking request. A decline carries the refund.
Links the buyer asked forA new link to change or cancel, and a resent invitation with the join link.
Recording and notes noticesA notice that a session was recorded, or that notes are ready.
Messages from the coachA coach’s own message to the buyer.
Emails to coaches and organization adminsEvery email to a coach or an admin comes from Talkspresso in every mode.

Talkspresso does not send thank-you, review request or book-again emails to buyers of bookings your platform created, in any mode. The coach can still write to the buyer, and those messages come from Talkspresso.

  • A coach agrees to be listed on your platform and agrees that you may cancel or move the sessions your members book. A cancel through the API refunds the buyer in full with no late or reschedule fee, even if the coach’s own policy would keep one. Talkspresso emails the coach when you cancel, and shows each move in the coach’s Talkspresso notifications.
  • If a coach’s consent is not in place when you cancel or move a session, the call is refused with 409 coach_consent_required, including for sessions already booked. Tell the buyer to contact the coach, or ask us for a new manage link for the buyer.
  • Talkspresso can raise the consent text. A coach who has not agreed to the new text leaves GET /providers until they do, and is asked on their next sign-in. A coach on the older text stays listed until we raise the requirement.
  • If your organization stops being ready (an agreement or fee needs renewing, for example), creating bookings and checkouts and moving bookings are refused with 403 org_not_ready. Reading bookings, cancelling and refunding, and replaying events keep working, so you can finish what is already in progress. Room links stop too, and rooms already shown in your page stop loading.

Show the room in your page

The room can open inside your own page, so the buyer never leaves it. What the buyer sees depends on the browser:

Where the room opens, by browser
Chrome and EdgeThe buyer joins inside your page.
Safari and Firefox, including every browser on iPhoneThe waiting room opens in its own window. Your frame shows “Open the call in its own window to join”, with no Join button, and the buyer joins there. Plan for this.
  1. Your server

    GET /bookings/:id/room-links when the buyer is about to join. You get url, embed_url and parent_origins. The link is for the buyer only.

  2. Your page

    Put embed_url in an iframe on a website we registered for you, with allow="camera; microphone; autoplay; fullscreen". Also offer “Open in a new tab” with url.

  3. Talkspresso

    Shows the waiting room inside your page. The buyer waits there until the coach lets them in. The notices that a session is recorded or that AI notes are on appear inside your frame.

  4. Your page

    Listen for messages from the room (joined, left, ended) and update your screens.

Get the buyer's room link
curl -s "$API/bookings/BOOKING_ID/room-links" \
  -H "Authorization: Bearer $TSP_KEY"
Response 200
{
  "data": {
    "booking_id": "cmwecj3ax00dm1vjzdl3ceij7",
    "role": "buyer",
    "url": "https://staging.talkspresso.com/meet/SESSION_ID?cid=BUYER_ID&ct=BUYER_TOKEN",
    "embed_url": "https://staging.talkspresso.com/meet/SESSION_ID?cid=BUYER_ID&ct=BUYER_TOKEN&embed=1",
    "parent_origins": [
      "https://staging.talkspresso.com",
      "https://partner-e2e.example.com"
    ],
    "session_ends_at": "2026-11-17T16:30:00.000Z"
  }
}

parent_origins are the websites we registered to show this room. The room refuses to load inside any other page. session_ends_at is when the booked time ends.

Frame the room and listen to it
<iframe
  id="room"
  src="EMBED_URL_FROM_YOUR_SERVER"
  allow="camera; microphone; autoplay; fullscreen"
  style="width:100%;height:640px;border:0"
></iframe>

<script>
  // Messages come only from the room's own address, which is the host of the url we gave you.
  const roomOrigin = new URL("EMBED_URL_FROM_YOUR_SERVER").origin;
  window.addEventListener("message", (event) => {
    if (event.origin !== roomOrigin) return;
    const m = event.data;
    if (!m || m.type !== "talkspresso-room-event") return;
    if (m.event === "joined") console.log("buyer is in the room");
    if (m.event === "left" || m.event === "ended") console.log("call over", m.session_id);
  });
</script>

What the room sends to your page, and only to a website on that list:

Message from the room
{ "type": "talkspresso-room-event", "version": 1, "event": "joined", "session_id": "..." }
  • joined: the buyer is in the call.
  • left: the buyer left.
  • ended: the call is over.

The room only sends messages to your page. It does not receive any from your page, so your page cannot control the call. The buyer taps to join, so the browser can ask for permission. If there is a camera or microphone problem, the room shows a plain instruction.

Things to plan for:

  • Talkspresso has to switch this on for your organization (the video setting is “inside your own page”) and register your website. Until then, GET /bookings/:id/room-links answers 409 video_mode_not_enabled. A change we make to your website list or this setting can take up to about 90 seconds to reach rooms.
  • Use allow="camera; microphone; autoplay; fullscreen" on the iframe. Without it the browser blocks the camera and microphone and the buyer sees a plain instruction.
  • The room shows the buyer the notices that the session is recorded or that AI notes are on, and offers Join only after the buyer has seen them in full. If something on your page covers the frame, even something see-through that fills the screen (a cookie banner layer or a chat widget container), Join is withheld and the buyer is offered the own-window path. The notices must also sit fully inside the visible part of your page, so the buyer may have to scroll your page until the whole frame is in view.
  • A buyer can join only near the session time. The buyer’s call link stops working two hours after the session ends (this holds for every buyer call link, not only these), and room links stop 15 minutes after it ends. Until then, whoever holds the link can join as the buyer, so keep it on your server and give it only to that buyer.
  • Make the frame at least 300 pixels wide and 380 pixels tall. In a smaller frame, the buyer is offered a button to open the call in a new window.
  • A buyer’s link is tied to one browser at a time. If it is opened in a second browser while the first is in the room, the room asks for a name and asks the coach to let that person in.
  • The coach hosts from Talkspresso. Host controls are not available inside your page. Only adults are supported, so a booking for a minor is never shown in a frame.
Room link errors
403 org_not_readyYour organization is not ready to use the partner API. Email support@talkspresso.com.
409 video_mode_not_enabledShowing the room inside your page is not switched on for your organization. Email support@talkspresso.com.
409 session_overThe session ended more than 15 minutes ago, so there is no room link.
409 no_allowed_originsWe have not registered the website that will show the room. Ask us to add it.
409 booking_cancelledThe booking is cancelled.
409 not_a_video_bookingThe session is in person and has no video room.
409 room_unavailableThe booking has no room link yet.
429 room_link_rate_limitedMore than 60 room links in an hour.

4. Webhooks

A webhook is a message we send to a web address on your server when something happens, so you do not have to keep asking. Talkspresso registers your address and gives you a signing secret for it. A key cannot create or change endpoints. This is on purpose. Send us the https address (port 443, a public host). We set it up and send it a ping.

Events

Webhook events
booking.createdA booking from your platform was created (free, or paid and confirmed).
booking.paidPayment for the booking was collected.
booking.rescheduledThe start time changed, by you, the buyer or the coach.
booking.cancelledThe booking was cancelled. cancelled_by says buyer, coach, partner or system.
booking.completedThe session took place and finished.
checkout.paidThe buyer paid a checkout you opened.
checkout.expiredA checkout ended unpaid after 30 minutes.
pingA test event we send when your endpoint is set up. It carries no buyer data.

What a delivery looks like

Each delivery is a POST with a JSON body. The outer wrapper is small and has a version number. The booking is inside data.object. The body never contains a join link, notes, intake answers or fee detail. If you need the join link, fetch the booking with GET /bookings/:id.

booking.created
{
  "id": "evt_c4c240afd8fb3bf3119275fe",
  "data": {
    "object": {
      "id": "cmwecn7jw00hw1vjz0y1ncjo4",
      "buyer": {
        "name": "Sam Rivera",
        "email": "sam@example.com"
      },
      "object": "booking",
      "status": "active",
      "service": {
        "id": "svc_sn_andre_williams_mentor",
        "title": "1:1 Mentorship Session"
      },
      "currency": "USD",
      "end_time": "2026-11-17T18:00:00.000Z",
      "provider": {
        "id": "sn_andre",
        "name": "Andre Williams"
      },
      "paid_cents": 0,
      "start_time": "2026-11-17T17:30:00.000Z",
      "updated_at": "2026-11-13T02:20:09.596Z",
      "partner_ref": "s5-wh-1794536409",
      "cancelled_by": null,
      "approval_status": "auto_approved",
      "session_outcome": null,
      "duration_minutes": 30
    }
  },
  "type": "booking.created",
  "created": "2026-11-13T02:20:09.633Z",
  "api_version": "2026-11-12",
  "organization_id": "org_startupnash_2024"
}
booking.cancelled (same shape, cancelled_by is filled in)
{
  "id": "evt_17c41458ff5377dacb31814d",
  "data": {
    "object": {
      "id": "cmwecn7jw00hw1vjz0y1ncjo4",
      "buyer": {
        "name": "Sam Rivera",
        "email": "sam@example.com"
      },
      "object": "booking",
      "status": "cancelled",
      "service": {
        "id": "svc_sn_andre_williams_mentor",
        "title": "1:1 Mentorship Session"
      },
      "currency": "USD",
      "end_time": "2026-11-17T18:00:00.000Z",
      "provider": {
        "id": "sn_andre",
        "name": "Andre Williams"
      },
      "paid_cents": 0,
      "start_time": "2026-11-17T17:30:00.000Z",
      "updated_at": "2026-11-13T02:21:02.114Z",
      "partner_ref": "s5-wh-1794536409",
      "cancelled_by": "partner",
      "approval_status": "auto_approved",
      "session_outcome": null,
      "duration_minutes": 30
    }
  },
  "type": "booking.cancelled",
  "created": "2026-11-13T02:21:02.168Z",
  "api_version": "2026-11-12",
  "organization_id": "org_startupnash_2024"
}
Booking object fields
id, objectThe booking id, and the value booking.
status, approval_statusactive or cancelled (also awaiting_payment and completed when you read a booking), and the approval state.
start_time, end_time, duration_minutesUTC times and length.
provider.id, provider.nameThe coach.
service.id, service.titleThe session.
buyer.name, buyer.emailThe buyer you sent us. Only for bookings your platform created.
partner_refYour reference, or null.
paid_cents, currencyWhat the buyer paid, in cents, and USD.
session_outcome, cancelled_byHow the session ended, and who cancelled it, when they apply.
updated_atWhen the booking last changed. Use it to ignore an older event that arrives late.

A checkout event has object set to checkout, and carries id, status, partner_ref, booking_id, provider_id, service_id, start_time, expires_at and updated_at.

Webhook request headers
Talkspresso-Signaturet=<unix seconds>,v1=<hex signature>. Two v1 values appear while we rotate your secret.
Talkspresso-Event-IdThe event id, the same on every delivery and replay of that event.
Talkspresso-Event-TypeFor example booking.created.
Talkspresso-Delivery-IdThe id of this delivery.
Talkspresso-Delivery-Attempt1 for the first try, 2 for the next, and so on.

Check the signature

Anyone can send a POST to your address. The signature proves a delivery is from us and was not changed. Do these in order:

  1. Read the raw body bytes exactly as they arrive, before any JSON parsing. Re-serialized JSON will not match.
  2. Read t and every v1 from the Talkspresso-Signature header.
  3. Reject the delivery if t is more than 5 minutes from your clock.
  4. Compute an HMAC-SHA256 of t, a dot and the raw body, using your signing secret. Write the result in lowercase hex.
  5. Compare it with each v1 in constant time. If any one matches, the delivery is real.
  6. Remember the event id and ignore an id you already handled: the same event can arrive more than once.
  7. Answer with any 2xx within 10 seconds. Do the slow work after you answer.
Node: a receiver that verifies
// Talkspresso webhook receiver: checks the signature, then the event.
// Run: TALKSPRESSO_WEBHOOK_SECRET=... node receiver.mjs
import crypto from "node:crypto";
import http from "node:http";

const SECRET = process.env.TALKSPRESSO_WEBHOOK_SECRET; // one secret per endpoint, from Talkspresso
const TOLERANCE_SECONDS = 300;
const seen = new Set(); // use your database in production

// header looks like: t=1794536400,v1=<hex>[,v1=<hex>]  (two v1 values while a secret is being rotated)
const verify = (header, rawBody, secret) => {
  if (!header) return false;
  let t = null;
  const sigs = [];
  for (const part of header.split(",")) {
    const i = part.indexOf("=");
    if (i < 0) return false;
    const key = part.slice(0, i).trim();
    const value = part.slice(i + 1).trim();
    if (key === "t") t = Number(value);
    if (key === "v1") sigs.push(value);
  }
  if (!Number.isFinite(t) || sigs.length === 0) return false;
  if (Math.abs(Date.now() / 1000 - t) > TOLERANCE_SECONDS) return false; // too old or too new
  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`, "utf8").digest();
  return sigs.some((s) => /^[0-9a-f]{64}$/.test(s) && crypto.timingSafeEqual(Buffer.from(s, "hex"), expected));
};

http
  .createServer((req, res) => {
    const chunks = [];
    req.on("data", (c) => chunks.push(c));
    req.on("end", () => {
      const rawBody = Buffer.concat(chunks).toString("utf8"); // the exact bytes, before any JSON parsing
      if (!verify(req.headers["talkspresso-signature"], rawBody, SECRET)) {
        res.writeHead(400).end("bad signature");
        return;
      }
      const event = JSON.parse(rawBody);
      if (!seen.has(event.id)) {
        seen.add(event.id);
        console.log(event.type, event.data.object.id, event.data.object.status ?? "");
      }
      res.writeHead(200).end("ok"); // any 2xx means delivered
    });
  })
  .listen(Number(process.env.PORT || 8787));
Python: the same check
# Check one Talkspresso webhook delivery. Pass the exact raw request body, not re-serialized JSON.
import hashlib
import hmac
import time

TOLERANCE_SECONDS = 300


def verify(signature_header: str, raw_body: bytes, secret: str) -> bool:
    if not signature_header:
        return False
    timestamp = None
    signatures = []
    for part in signature_header.split(","):
        key, _, value = part.strip().partition("=")
        if key == "t" and value.isascii() and value.isdigit():
            timestamp = int(value)
        elif key == "v1":
            signatures.append(value)
    if timestamp is None or not signatures:
        return False
    if abs(time.time() - timestamp) > TOLERANCE_SECONDS:
        return False
    signed = str(timestamp).encode() + b"." + raw_body
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return any(hmac.compare_digest(expected.encode(), s.encode()) for s in signatures)

We sent a real ping and a real booking.created from staging to the Node receiver above, and the receiver accepted both.

Retries, replay and catching up

How delivery behaves
SuccessAny 2xx answer within 10 seconds.
RetriesIf you answer with anything other than 2xx, or you time out, we try again after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 12 hours and 24 hours: that is seven retries, eight tries in all, over about 44 hours. Every retry sends the same body, unchanged, with a new signature.
After the last tryThe delivery is marked abandoned. The event is still in GET /events and you can ask us to send it again.
Answer 410 GoneWe turn the endpoint off right away. Answer 410 only when you have stopped using that address.
A day of failuresIf every delivery fails for 24 hours, we pause the endpoint and hold your events. Nothing is dropped. We contact you. When your receiver is working again, we resume and send the held events.
OrderEvents can arrive out of order and more than once. Use the event id to ignore repeats and updated_at to ignore an older state.
ReplayPOST /events/:id/replay sends one event again with the stored payload, up to 5 times an hour. Deliveries and their results are in GET /webhook-deliveries.
Catching upGET /events?since=<last event id>&type=...&limit=... returns events oldest first. It is the same data as the webhooks. An event shows up here about 30 seconds after it happens.
How long we keep buyer details in eventsWe remove the buyer’s name and email from an event after 90 days. The id, type and time stay.
Read the event feed
curl -s "$API/events?limit=50" \
  -H "Authorization: Bearer $TSP_KEY"

# next page: pass the last event id back
curl -s "$API/events?since=evt_8c8a5fba318e1a4daa0570b3&limit=50" \
  -H "Authorization: Bearer $TSP_KEY"
Response 200
{
  "data": [
    "...events in order, oldest first..."
  ],
  "has_more": true,
  "next_cursor": "evt_992beaad97620c2cb562b057"
}
Send one event again
curl -s -X POST "$API/events/evt_8c8a5fba318e1a4daa0570b3/replay" \
  -H "Authorization: Bearer $TSP_KEY"
Response 200 (queued_deliveries is how many endpoints it went to)
{
  "data": {
    "event_id": "evt_92175b0a3de3dc94bc49d768",
    "queued_deliveries": 0
  }
}
See your endpoints and recent deliveries
curl -s "$API/webhook-endpoints" -H "Authorization: Bearer $TSP_KEY"
curl -s "$API/webhook-deliveries?limit=20" -H "Authorization: Bearer $TSP_KEY"
Endpoints
{
  "data": [
    {
      "id": "whe_ba03b4efeda4fa78c4a5d910",
      "url": "https://hooks.example.com/talkspresso",
      "events": [],
      "status": "active",
      "disabled_reason": null,
      "consecutive_failures": 0,
      "last_success_at": null,
      "created_at": "2026-11-13T02:22:55.776Z"
    }
  ]
}
Deliveries
{
  "data": [
    {
      "id": "whd_fd4816cfe0914e269290cdd039312342",
      "event_id": "evt_e910558c2b61b3cc03d4c1a0",
      "endpoint_id": "whe_ba03b4efeda4fa78c4a5d910",
      "status": "delivered",
      "attempts": 1,
      "next_attempt_at": null,
      "last_status_code": 200,
      "last_error_class": null,
      "duration_ms": 140,
      "delivered_at": "2026-11-13T02:23:05.071Z",
      "replays": 0,
      "created_at": "2026-11-13T02:23:05.071Z"
    }
  ]
}

5. Settings you control and settings Talkspresso sets

Your organization has a Partner settings screen for owners and admins. It shows each setting, who can change it, when it last changed and your go-live checklist. Your developers can read the same data with GET /settings.

You control

Settings a partner controls
Where your members bookOnly inside your own platform, or also on a Talkspresso page for your organization.
Who sends booking emailsTalkspresso plain, Talkspresso with your name and logo, or your platform. See “Booking emails”.
Who can join your rosterOnly people you invite, or people can apply and you approve each one.
Your name and lookOrganization name, logo, colors, tagline and contact and support email.
Your coachesWhich coaches you invite, and each coach’s title on your platform.
What your server does with an eventEverything your server does after we deliver an event.

Talkspresso sets, after your agreement

These can affect money, buyer data and compliance, so we set them with you. Email support@talkspresso.com to ask for a change. Every change is recorded with who made it and why.

Settings Talkspresso sets
How buyers payEach coach is paid directly through the coach’s own PayPal account.
Who the buyer isA guest. You send a name and an email. No Talkspresso account is needed.
Which bookings you receiveThe bookings your platform created, and no others.
Who may attendAdults only. Health records (HIPAA) mode is off for partner platforms.
Where the video call opensOn a Talkspresso page, or inside your own page. Talkspresso sets this, and registers the website that will show the room.
Talkspresso’s feeSet in your agreement for bookings from your platform, as a percentage. It cannot be set above 30 percent.
Which coaches may be listedA coach is listed only after agreeing to the current consent text (see “Coach consent”).
Registered addressesWhere buyers return after paying, which websites may show the video room, and where webhooks go.
Keys and secretsWe create, rotate and revoke API keys and webhook secrets. Nobody with a key can change them.
Going liveWe decide when the checklist is complete and turn on production.

6. What we never share and never allow

What we never share

What Talkspresso never shares with a partner
Coach or host linksNo API response, webhook or room link contains a link that lets someone host or control a call. You only ever receive the buyer’s link.
Raw video tokensVideo session tokens never appear in any response. You do not need them: the room link is enough.
What was said in a sessionNo recordings, transcripts, AI notes or summaries. Webhooks and API answers do not contain them.
Coach contact detailsA coach’s email, phone and payout details are not shared.
Payout and fee detailYou see what the buyer paid. You do not see what the coach earned or what the fee was.
Other people’s bookingsYou see only bookings your platform created. You cannot read a booking a buyer made on a coach’s own Talkspresso page, even if the coach is on your roster.
More about the buyer than you sentWebhooks and bookings carry the buyer’s name and email. Intake answers are available only through an API call with your key, for your own bookings. They are never in a webhook.

What we never allow, or do not support yet

What a partner platform cannot do
Single sign-onNot available yet. Buyers are guests identified by the name and email you send.
Under 18Adults only. Minors are not supported.
Buyers outside the United StatesUS buyers only for now. The pages and emails are in English and prices are in US dollars.
Health recordsCoaches in health records (HIPAA) mode do not appear, and partner platforms cannot use that mode.
Changing money or settings with a keyA key cannot change settings, fees or webhook endpoints, and cannot create or revoke keys.
Hiding Talkspresso on the payment pageThe payment page keeps the coach, the price, the cancellation rule and the line that Talkspresso collects the payment through PayPal. You cannot hide them.
Hiding recording and AI notes noticesThe room tells buyers when a session is recorded or AI notes are on. A frame cannot hide that.
Host controls inside your pageThe coach hosts from Talkspresso. A host who opens the room inside a frame is offered a button to open it in a new window.

Your part

Your agreement sets out your obligations. In short:

  • Keep your key on your server and out of your pages, your mobile apps and your logs. Tell us at once if it leaks and we will revoke it.
  • Use the API for your own platform and your own members only. Do not reuse the coach list for anything else, and do not present yourself as Talkspresso.
  • Cancel a booking only for a reason in the reason code list, and send the matching code. A cancel through the API refunds the buyer in full with no late fee. Do not use it to avoid a fee the buyer’s own cancellation would have caused. Keep a record of the buyer’s request.
  • Do not promise buyers a different refund or cancellation rule than the one they accepted when they paid.
  • Offer adults and US buyers only.

7. Sandbox

The sandbox is our staging system with a staging copy of your organization. Build here first.

Sandbox keys
How to get oneEmail support@talkspresso.com. We create a sandbox key for your staging organization and give it to you by a method other than email.
How long it lasts14 days. Ask for a new one when it ends.
Where it worksOnly on https://api-staging.talkspresso.com/partner/v1. On production it is refused with 401.
What it is notIt is not a production key. Having one does not mean you are ready to go live.
Real peopleUse made-up buyers with email addresses you control. Staging is a test system.
LimitsThe same limits as a new production key (see “Limits” in section 3).

What you can book against

Sandbox test data
OrganizationA staging copy of your organization. In this guide the examples use our test organization, StartupNash (id org_startupnash_2024).
Free sessionsEvery test coach offers a free 30 minute “1:1 Mentorship Session”. Example: coach sn_andre, service svc_sn_andre_williams_mentor. GET /providers lists all of them.
A paid sessionOne test coach offers a paid session you can open a checkout for, and pay with PayPal sandbox. In our run: coach cmlrh3wdm002l1qhg56q14ydj, service svc-ppcp-walkthrough-50, $50. Ask us if your staging organization does not have one yet.
PayingUse a PayPal sandbox buyer login. Ask us for one. No real money moves.
Return addressIn our run the registered return host is partner-e2e.example.com. Yours is whatever you gave us.
Ids in this guideThey come from our own test run. Use the ids your own calls return.

Staging and production use different base addresses: https://api-staging.talkspresso.com/partner/v1 and https://api.talkspresso.com/partner/v1. When you switch to production, change only the base address. We register your payment return address and webhook address separately for staging and for production.

8. Go-live checklist

This is what we check before we create your production key. You can see each item and its status in your Partner settings screen, or from GET /settings. An item says who has to act and what is still blocking it.

Yours

You can do these from your organization settings, or ask us.

Go-live checklist: Yours
At least one coach listedAt least one coach is on your roster and can be booked.
Seller name and contact emailBuyers can see your organization’s name and a contact email.
Roster is not open to anyonePeople either apply and you approve each one, or you invite them.
Public page matches your setupIf your members book inside your own platform, your public Talkspresso page is switched off.

Talkspresso

We do these. You can see each one in your settings.

Go-live checklist: Talkspresso
Agreement signedThe agreement schedule is signed and matches your settings.
Adults only confirmationWe have your written confirmation that your members and buyers are adults.
Organization activeYour organization is active and is not in health records (HIPAA) mode.
Dedicated key ownerYour key belongs to an account that manages only your organization.
Return address registeredThe web address buyers return to after paying is on file.
Allowed websitesOnly if you show the video room inside your page: the website that will show it is on file.
Privacy Policy and Terms updatedOur public Privacy Policy and Terms mention partner platforms.
How buyers pay is readyEach coach can be paid directly through PayPal.
Settings chosen on purposeEach of these was set on purpose: how buyers pay, who buys, which bookings you receive, who may attend and where the call opens.
Fee on bookings setTalkspresso’s fee on bookings from your platform is set in your agreement.
Fee applied to every bookingThat fee is applied to every booking from your platform.
Coaches agreed to be listedEvery listed coach has agreed to be listed on your platform.
Booking emailsWho sends the buyer’s booking emails is chosen. If your platform sends them, you also have a webhook endpoint that receives booking.created.
Test payment runA paid test booking and refund with your final settings and fee is on file.
Key expiryYour key has not expired and does not expire soon.

Your developers

You do this one.

Go-live checklist: Your developers
Webhook endpointYou gave us a web address that receives webhooks. If you would rather ask us for events yourself, use GET /events instead.

Production keys last a year. You can hold two at once, so you can switch to the new one without a gap. We create the replacement before the old one ends and we revoke the old key when you tell us the new one works. If a key leaks, tell us and we revoke it at once.

Questions, a sandbox key or a change to a setting? Email support@talkspresso.com.

9. Developer kit

Everything a developer needs to start without reading this whole guide first: a machine-readable description of the API, a Postman collection, and a small working sample website.

The developer kit
API description (OpenAPI 3.1)Every call in this guide, with its fields, answers and error codes. The live copy needs no key. The saved copy is committed with our website and updated with each release. Load either one into a tool that reads OpenAPI to make a client library or a test page.
Postman collectionThe same calls, ready to send. Download it, import it into Postman, and fill in the partner_api_key variable with your sandbox key. The base address is already the staging address, and every create call sends its own Idempotency-Key.
Sample teacher platformA small working website that lists coaches, shows their times, books a session, sends the buyer to our hosted payment page, receives webhooks and shows the video room. It is being published as open source. Email support@talkspresso.com and we send you a copy today.
Sandbox keyEmail support@talkspresso.com. Staging only, lasts 14 days, and we give it to you by a method other than email. See section 7.
  • Live API description: https://api-staging.talkspresso.com/partner/v1/openapi.json
  • Saved copy: https://talkspresso.com/partner/openapi.json
  • Postman collection: https://talkspresso.com/partner/talkspresso-partner.postman_collection.json

Open the live API description, open the saved copy, or download the Postman collection.

Good to know

  • The description follows the code. If this guide and the description ever differ, the description on staging is right, and we want to hear about it.
  • The saved copy can be a few days behind the live copy on staging. Use the live copy when you need the newest fields.
  • On the production address the live copy answers once the partner API is turned on for production. Until then, use the staging address.

Free to start. No credit card.

Partner guide | Talkspresso