Unable to Create Booking

I’ve been trying to create a booking and am unable to get it to work.

I’ve tried posting to the following two URL’s:
api.youcanbook.me/v1/profiles/{profileId}/bookings

and

/v1/{accountId}/profiles/{profileId}/bookings

Neither seems to work.

The JSON I’m passing over looks like this:

{
   "startsAt":"2024-05-10T08:00:00",
   "timeZone":"America/Denver",
   "units":1,
   "numberOfSlots":1,
   "answers":[
      {
         "code":"FNAME",
         "string":"Test"
      },
      {
         "code":"LNAME",
         "string":"Testing"
      },
      {
         "code":"PHONE",
         "string":"8884718888"
      },
      {
         "code":"EMAIL",
         "string":"emailtest"
      },
      {
         "code":"ADDRESS",
         "string":"51 W 150 S"
      },
      {
         "code":"CITY",
         "string":"Lehi"
      },
      {
         "code":"STATE",
         "string":"UT"
      },
      {
         "code":"ZIP",
         "string":"84043"
      },
      {
         "code":"LEADTYPE",
         "string":"G3-Direct"
      },
      {
         "code":"Q9",
         "string":"testing"
      },
      {
         "code":"NOTES",
         "string":""
      }
   ]
}

And I’m currently getting this response:

{
   "code":"ycbm_api_invalid_selections",
   "errors":[
      {
         "code":"time_zone_non_editable",
         "message":"Time zone is not overridable",
         "object":""
      }
   ],
   "httpCode":400,
   "httpStatusCode":400,
   "message":"Invalid selections",
   "status":"BAD_REQUEST",
   "type":"YcbmApiException"
}

I’ve removed timeZone but it’s required. What am I missing when creating a booking?
Thanks in advance!

@Ben I found the added documentation on the ‘intents’ model from a different post. However, when I try and create a booking using that route I get this response:

{
   "code":"ycbm_api_profile_not_found",
   "errors":[
      
   ],
   "httpCode":404,
   "httpStatusCode":404,
   "message":"Profile not found",
   "status":"NOT_FOUND",
   "type":"YcbmApiException"
}

The post data I’m passing in is:

{
   "sudomain":"oh-cincinnati",
   "selections":{
      "timeZone":"America\/New_York"
   }
}

Maybe subdomain is a key instead of the actual subdomain of the booking page I’m wanting to use?

This should work. First create a POST to the intents endpoint: https://api.youcanbook.me/v1/intents

This will get you an intentId

This should return you with an intent Id, then you can PATCH in your selections, or use them in the original post:

{
  "selections" : {
    "appointmentTypeIds" : ["jsid213858"],
    "duration" : null,
    "form" : [ {
      "id" : "LNAME",
      "value" : "Test"
    }, {
      "id" : "EMAIL",
      "value" : "ben@domain.com"
    }, {
      "id" : "FNAME",
      "value" : "Ben"
    } ],
    "startsAt" : null,
    "teamMemberId" : "AUTO",
    "timeZone" : "Europe/Madrid",
    "units" : null
  }
}

You can include all you need for the booking what is required for your fields.

Then confirm with the intentId:
https://api.youcanbook.me/v1/intents/{intentId}/confirm

That’s the problem I’m running in to. Even if the only thing I pass over is a subdomain I still get this response:

{
   "code":"ycbm_api_profile_not_found",
   "errors":[
      
   ],
   "httpCode":404,
   "httpStatusCode":404,
   "message":"Profile not found",
   "status":"NOT_FOUND",
   "type":"YcbmApiException"
}

Maybe because that booking page was created by one of the other users? Shouldn’t an admin have access to all of them under the account?

You are missing a b in subdomain, it should be:
{
“subdomain”:“oh-cincinnati”
}

You only need to pass in a timezone on a booking page that has an override option, or where we are detecting the booker’s timezone from their IP.

(facepalm) Thanks Ben. I only sent a billion test calls to your system trying to get that to work… with a spelling error… I’ll update that and see if I can wrap up getting bookings to send over today.

@Ben
Almost there. When I set the team member id to “Auto” I get the following:

{
   "code":"ycbm_api_intent_misconfigured",
   "errors":[
      {
         "code":"invalid_team_member_selected",
         "message":"Selected team member is invalid (AUTO)",
         "object":""
      }
   ],
   "httpCode":409,
   "httpStatusCode":409,
   "message":"Intent misconfigured",
   "status":"CONFLICT",
   "type":"YcbmApiException"
}

This is what my intent looks like:

{
   "bookingId":null,
   "createdAt":1715383912134,
   "id":"itt_intentid",
   "intentStatus":"SETTING_UP",
   "selections":{
      "appointmentTypeIds":null,
      "duration":null,
      "form":[
         {
            "id":"ZIP",
            "value":"45402"
         },
         {
            "id":"NOTES",
            "value":""
         },
         {
            "id":"LNAME",
            "value":"Test"
         },
         {
            "id":"CITY",
            "value":"Test"
         },
         {
            "id":"PHONE",
            "value":"8888888989"
         },
         {
            "id":"ADDRESS",
            "value":"427 Main St"
         },
         {
            "id":"STATE",
            "value":"OH"
         },
         {
            "id":"SETTER",
            "value":"emailaddress"
         },
         {
            "id":"EMAIL",
            "value":"emailaddress"
         },
         {
            "id":"LEADTYPE",
            "value":"Paid Lead-Live"
         },
         {
            "id":"FNAME",
            "value":"Tester"
         }
      ],
      "startsAt":1715868000000,
      "teamMemberId":"AUTO",
      "timeZone":null,
      "units":null
   }
}

I’ve verified that time is available in the calendar. Thanks.

Try sending this:

{"form":[
         {
            "id":"ZIP",
            "value":"45402"
         },
         {
            "id":"NOTES",
            "value":""
         },
         {
            "id":"LNAME",
            "value":"Test"
         },
         {
            "id":"CITY",
            "value":"Test"
         },
         {
            "id":"PHONE",
            "value":"8888888989"
         },
         {
            "id":"ADDRESS",
            "value":"427 Main St"
         },
         {
            "id":"STATE",
            "value":"OH"
         },
         {
            "id":"SETTER",
            "value":"emailaddress"
         },
         {
            "id":"EMAIL",
            "value":"emailaddress@domain.com"
         },
         {
            "id":"LEADTYPE",
            "value":"Paid Lead-Live"
         },
         {
            "id":"FNAME",
            "value":"Tester"
         }
      ],
      "teamMemberId":"AUTO",
      "timeZone":"US/Central"
}

Through to a PATCH https://api.youcanbook.me/v1/intents/{intentId}/selections

This should allow you to confirm things here with a PATCH:
https://api.youcanbook.me/v1/intents/{intentId}/confirm

As long as the CAPTCHA challenge is turned off from the booking page.

It does let me PATCH the intent and set the teamMemberId to Auto. It’s when I hit the confirm endpoint that I get the error:
“code”:“invalid_team_member_selected”,
“message”:“Selected team member is invalid (AUTO)”

Heyy, :slight_smile:
I have the exact same problem, I have followed each step on the documentation:
All my calls are successful except the last one to confirm the booking, I always get a 409 ‘Intent misconfigured’.
Is it normal that there is so much calls that I need to make in order to make one booking?

  1. POST new intent
  2. PATCH intent selections
  3. GET availability key
  4. GET avalabilities
    5. PATCH intent to confirm booking ← This one is returning 409.

@Ben Sorry I know you’re busy but I’m still getting the same thing after I PATCH the intent to confirm the booking. It’s still telling me that ‘AUTO’ is an invalid team member. Any ideas?

@g3Mark sorry on the delay. When you submit your confirmation you can leave off the “teamMemberId”:“AUTO” as this should have been established during the initial PATCH to selections.

You can also try submitting the confirmation with a blank payload { }

@Ben Still the same thing. I can create this intent successfully:

{
   "bookingId":null,
   "createdAt":1715962477731,
   "id":"itt_6c0ef3d0-e5fc-476e-a2d4-1b7cd17ddb8d",
   "intentStatus":"SETTING_UP",
   "selections":{
      "appointmentTypeIds":null,
      "duration":null,
      "form":[
         {
            "id":"ZIP",
            "value":"45402"
         },
         {
            "id":"NOTES",
            "value":""
         },
         {
            "id":"LNAME",
            "value":"Jackson"
         },
         {
            "id":"CITY",
            "value":"Eaton"
         },
         {
            "id":"PHONE",
            "value":"888888888"
         },
         {
            "id":"ADDRESS",
            "value":"427 Test St"
         },
         {
            "id":"STATE",
            "value":"OH"
         },
         {
            "id":"SETTER",
            "value":"testvalue@email.com"
         },
         {
            "id":"EMAIL",
            "value":"testvalue@email.com"
         },
         {
            "id":"LEADTYPE",
            "value":"Test Lead Type"
         },
         {
            "id":"FNAME",
            "value":"Test"
         }
      ],
      "startsAt":1716213600000,
      "teamMemberId":"AUTO",
      "timeZone":null,
      "units":null
   }
}

That should be eveything needed so I PATCH an empty payload ‘{}’ https://api.youcanbook.me/v1/intents/itt_6c0ef3d0-e5fc-476e-a2d4-1b7cd17ddb8d/confirm

And then I get the response back that ‘Auto’ isn’t a valid team member ID:

{
   "code":"ycbm_api_intent_misconfigured",
   "errors":[
      {
         "code":"invalid_team_member_selected",
         "message":"Selected team member is invalid (AUTO)",
         "object":""
      }
   ],
   "httpCode":409,
   "httpStatusCode":409,
   "message":"Intent misconfigured",
   "status":"CONFLICT",
   "type":"YcbmApiException"
}

@g3Mark Checking with the development team on this specifically as I am able to replicate this same error. It could be potentially with the Order setting in the UI here:

@hdev you can simplify things with adding your selections in the initial POST, but you would need to generate the availability key to pull in available times.

@Ben how can I do this please? Would be be available for a 5 minutes call please? I’m helpless right now no customers can book me and my monthly subscriptions is still on.

I think that to get a response I need to get the intent id first right?

@hdev yes, the first POST gets you the intentId which then you can update and confirm. If you need bookings immediately I would suggest using the embed option or sending folks to your booking page link (something.youcanbook.me). I am awaiting hearing back from the team on the errors you all are running into. I could potentially have a live q&a next week to answer API questions if you and others are interested.

@g3Mark ok I have heard back from the team. For this “teamMemberId” : “AUTO” shouldn’t be passed into the first POST, but into a secondary PATCH, this should allow the system to select a Team Member, and in your GET for the intent you will see “teamMemberId” : “m122445” this will be replaced with the Id of the team member selected.

@Ben Thanks! One thing to note for anyone else trying to do this. You need to structure the PATCH different from the initial POST. I was patching to https://api.youcanbook.me/v1/intents/{intentId}/selections like this:

{
   "selections":{
      "teamMemberId":"AUTO",
      "form":[
         {
            "id":"FNAME",
            "value":"Mark "
         }
    }
}

Which is what it looks like on the initial post. However, it kept failing to update my intent. Turns out that when updating the intent the system isn’t expecting things to be inside of the “selections” object. So to get it to update you just send the selections object itself. The correct format for a PATCH is something like this:

{
  "teamMemberId":"AUTO",
  "form":[
     {
        "id":"FNAME",
        "value":"Mark "
     }
}

Then it works.

Hello @Ben

Sorry, I was a bit busy, here is how i call the api to make a booking step by step.
I can show you the request body too if you want, but they are a bit long.
Unfortunately I cannot redirect to my youcanbookme page, I need the user to stay on my website.

      // create intent with post
      const createIntentResponse = await axios.post(
          "https://api.youcanbook.me/v1/intents",
          createIntentPayload(req.body)
      )

      const intentId = createIntentResponse.data.id

      console.log("intent id: " + intentId)

      // patch intent with booking info
      const patchIntentResponse = await axios.patch(
          `https://api.youcanbook.me/v1/intents/${intentId}/selections`,
          patchIntentPayload(req.body)
      )

      console.log("intent patch response: " + patchIntentResponse.data)

      // get booking availibility key

      const availibilityKeyResp = await axios.get(
          `https://api.youcanbook.me/v1/intents/${intentId}/availabilitykey`
      )

      const availabilityKey = availibilityKeyResp.data.key

      console.log("avail key: " + availibilityKeyResp.data.key)

      const availibilitiesResp = await axios.get(
          `https://api.youcanbook.me/v1/availabilities/${availabilityKey}`
      )

      const unixTimsetampStartTime = availibilitiesResp.data.slots[0].startsAt;

      console.log("availabilities :" + JSON.stringify(availibilitiesResp.data.slots[0]))

      const intentConfirmationResp =  await axios.patch(
          `https://api.youcanbook.me/v1/intents/${intentId}/confirm`,
          postConfirmIntentPayload(unixTimsetampStartTime)
      )

      console.log("confirmation intent resp :" + JSON.stringify(intentConfirmationResp.data))



      const bookingResponse = await axios.post(
        getYCBMBookingURL(),
        createBookingPayload(req.body),
        getYCBMAxiosConfig()
      );

      console.log(bookingResponse)

      await axios.patch(
       getYCBMBookingURL() + `/${bookingResponse.data.id}`,
       createBookingAcceptedPayload(),
       getYCBMAxiosConfig()
      );

For this bit you may need to PATCH the startsAt back into the /selections end point and then submit a blank payload for the confirm PATCH.