How to persist assistant variables in a phone call...
# support
m
Scenario: I want the agent to look up the first and last name of the caller based on their caller number then address the caller immediately by their first name without ever asking for it. What I did: I set up an end point for the Server_URL, and it indeed is called at the beginning of the call. It contains the caller's phone number. I then use that to query my MYSQL database and obtain the first and last name. However, I do not know how to provide that first name, last name and call number back to the agent for use in the phone call. I tried https://api.vapi.ai/assistant/{assistant_id} with this payload: payload = { "metadata": { "caller_number": caller_number, "first_name": first_name, "last_name": last_name, "customer_id": customer_id } } .. but the agent still does not recognize the caller's name. Am I using the wrong API call? Is there a way to feed variables back to the agent during the call?
v
@Michael P It sounds like you're on the right track by attempting to pass the caller's information back to the agent. However, instead of using the metadata field, you should use the
assistantOverrides
with
variableValues
to pass dynamic variables during the call. Here's how you can do it: 1. When you receive the caller's phone number at your endpoint and look up their information in your database, prepare the data to be passed back to VAPI. 2. Use the
assistantOverrides
field with
variableValues
to set the dynamic variables such as
first_name
,
last_name
, and
caller_number
. 3. Make an API call to VAPI with the correct payload structure to update the call context. The payload should look something like this:
Copy code
json
{
  "assistantOverrides": {
    "variableValues": {
      "first_name": "John",
      "last_name": "Doe",
      "caller_number": "1234567890"
    }
  }
}
You would send this payload to the appropriate VAPI endpoint that is designed to update the call context with dynamic variables. If you're not sure which endpoint to use or how to structure the request correctly, please ask support for more info on this. They will be able to provide you with the specific details for your VAPI setup.
You can continue this conversation by mentioning me in the message.
m
Am I calling the correct API? I actually tried this first but I always get the following error: "property assistantOverrides should not exist". @User
@Sahil Any ideas on this? Been banging my head against the wall on this for a few weeks. The documentation clearly says to use assistantOverrides but whenever I call the API it always returns "property assistantOverrides should not exist".
e
you need to use a custom server or make to serve an assistant-request type of server call https://docs.vapi.ai/server-url/events Read the section titled "Retrieving Assistants"
You put the 'assistantOverrides' field in this payload when you retrieve the assistant
m
Thank you @ErikZ ! So I have a custom server URL, I called it https://my_server_domain/incoming_call and it successfully retrieves all the information I need. It is saving it back that is causing me the headache. Here is an abbreviated version of it: @app.route('/incoming_call', methods=['POST']) def incoming_call(): call_event = request.get_json(force=True) assistant_id = call_event.get('message', {}).get('call', {}).get('assistantId') caller_number = call_event.get('message', {}).get('call', {}).get('customer', {}).get('number') [snipping out part where I look up the first and last name from my DB] update_url = f"https://api.vapi.ai/assistant/{assistant_id}" headers = { "Authorization": f"Bearer {VAPI_API_KEY}", "Content-Type": "application/json" } payload = { "assistantId": assistant_id, "assistantOverrides": { "variableValues": { "first_name": first_name, "last_name": last_name, "customer_id": customer_id, "caller_number": caller_number } } } .. then I call the update_url and that is when it tells me assistantId and assistantOverrides are not valid. Am I calling the wrong API?
This is the error: {"message":["property assistantId should not exist","property assistantOverrides should not exist"],"error":"Bad Request","statusCode":400}
e
your server should be set in the serverUrl of VAPI and it should be able to handle the 'https://api.binarytint.com/api/webhook' endpoint
this endpoint will recieve a payload like this: {'message': {'type': 'assistant-request', 'call': {'id': '1d854e02-87d9-47c4-8e71-041c8eec3f07', 'orgId': '965bc02d-472a-49f9-8512-50dd6ce485a5', 'createdAt': '2024-07-27T19:44:02.568Z', 'updatedAt': '2024-07-27T19:44:02.568Z', 'type': 'inboundPhoneCall', 'status': 'ringing', 'phoneCallProvider': 'twilio' ...
m
OK. Not the Server URL in the Assistant?
Right now I set it in the Advanced tab of the assistant
e
no, you will not set the override variables in the assistant
you will set them when you return a transient assistant
you are talking about a persistent assistant
its confusing...Im aware
m
yeah would be great to see some sample code
I will give this a shot, good karma coming your way thank you
I cannot seem to set the Server URL, there is no save button on that page? I see a lot of questions about this, looks like a known issue. Is the only workaround to change it with an API call? https://cdn.discordapp.com/attachments/1266827885541458065/1266865566271016991/Screen_Shot_2024-07-27_at_5.10.46_PM.png?ex=66a6b400&is=66a56280&hm=12f8b97f4356deaf7a1d14302adc1c14ec10608ce695df160cfde0dd0329aa00&
s
@Michael P You can directly send me your server url. I will add it. Apart from it, just add the server url and wait for couple of minutes
it will be saved properly
m
Hi @Sahil - just spoke with support, it looks like I was indeed calling the wrong API. I was trying to call https://api.vapi.ai/assistant/{{assistant_id}} to set the dynamic variable but it looks like it should have been using the https://api.vapi.ai/call - I am going to try this and if it works I will close the ticket and add more information about how I fixed it to the community. Thank you!
Well, that does appear to be the right API call but something bizarre happens when I call it @Sahil @Shubham Bajaj - the agent starts calling my number over and over again! It looks like the format on the Dynamic Variables documentation page only for outbound calls. Do either of you know what the JSON payload should be for incoming calls? When I use this it says that I must include a customer number: payload = { "assistantId": assistant_id, "assistantOverrides": { "variableValues": { "first_name": first_name, "last_name": last_name, } }, "phoneNumberId": phone_id # } But when I add the customer number, that's when I start getting phone calls over and over again. payload = { "assistantId": assistant_id, "assistantOverrides": { "variableValues": { "first_name": first_name, "last_name": last_name, } }, "customer": { "number": caller_number }, "phoneNumberId": phone_id } Any ideas guys?
e
Let me explain how I got this working for my assistant, which I figured out just 2 days ago. 1. You need to have your own custom server URL handling requests 2. You need to have a phone number capable of receiving incoming calls 3. You dont want to set an assistant for the number(I.E you want it to say "Select Assistant..." 4. Your server will get a request to the endpoint when a call is made to that number: "https://.com/api/webhook" of type 'assistant-request' 5. You will need to query vapi for the assistant you want to return: api_url = f"https://api.vapi.ai/assistant/{assistant_id}" headers = { 'Authorization': f'Bearer {BEARER_TOKEN}' } response = requests.get(api_url, headers=headers) 6. Once you have the assistant data you will need to unset some of the returned fields: del assistant['id'] del assistant['orgId'] del assistant['createdAt'] del assistant['updatedAt'] del assistant['isServerUrlSecretSet'] 7. You are now able to change the assistant's prompt, effectively setting the variables yourself: payload['model']['messages'][0]['content'] = payload['model']['messages'][0]['content'].replace('{{now}}', now_formatted) payload['model']['messages'][0]['content'] = payload['model']['messages'][0]['content'].replace('{{date}}', date) payload['model']['messages'][0]['content'] = payload['model']['messages'][0]['content'].replace('{{time}}', time) 8. You can replace other variables or parts of your prompt, then you will want to return the assistant like this: assistant_json = {'assistant': assistant} return assistant_json https://cdn.discordapp.com/attachments/1266827885541458065/1267901211772981268/image.png?ex=66aa7885&is=66a92705&hm=58180cd7aeb8db2d9e96cc0a85e1b9dcc2096188ace10c87fbb354fada593a02&
This is alot of steps that you will have to set up, I gave examples of python code because my backend python server is set up with Python
I suggest checking out this github if you need somewhere to start with a backend: https://github.com/VapiAI/server-side-example-python-flask I'm not VAPI support, so I apologize I won't be able to hold your hand through this stuff, but hopefully this helps!
m
Thanks @ErikZ this is super helpful.
So @ErikZ the one thing I see you doing here is changing the prompt and I don't need to edit the prompt. I just need to store those dynamic variables. So what I see here is that you were able to extract fields from the assistant and update them, but any way to store new, dynamic variables? It sounds like from my support call it's that https://api.vapi.ai/call but that only seems to work for outbound calls. Whenever I call it, my phone starts ringing for a couple of minutes ๐Ÿ™‚
@Sahil @Shubham Bajaj Can https://api.vapi.ai/call be used for setting dynamic variables in inbound calls?
Thinking about this more @ErikZ I could I guess change the system prompt but that feels like it would be dangerous, because if I overwrite it, what if there are multiple callers? Seems like the best way is to use dynamic variables but I just can't figure out how to set them for inbound calls, only outbound calls. Let me see if I can pay someone in the community to help me because I've been programming for 30 years, I'm no novice, but I just can't get by this, there's not enough documentation.
I will set up another call with support too
e
You are not actually changing the system prompt
you are temporarily editing it for that specific caller
it will be the same as what it is on vapi.ai
s
yes it can be used for inbound calls with dynamic variables.
m
Question: when I called it, it insisted on the phone number field, but when I send a phone number, it immediately starts calling me
After I called that function, it changed my prompt permanently. Maybe I did something wrong
s
can you share more context please.
m
Iโ€™m on a runaway about to takeoff but Iโ€™ll post the code when I land. But I created the assistant, set the server URL, then received the call to the server URL, and tried to set the dynamic variables using assistant override with the /call endpoint. I call the agent, she answers, then immediately (while Iโ€™m still on the phone with the agent) I start to receive phone calls from the same agent. And she keeps calling and calling.
I was joking with my partner that she was like a crazy ex-girlfriend ๐Ÿ˜‚ because she calls and calls and calls
So I tried not providing a phone number field in the api call but it seems it is required
s
you might have added the transfer call function with your number and triggered it in your prompt because of this your getting calls. to verify try chaning the call forwarding number if this is the issue please work on your prompt if not then please share the call id.
c
This is wrong.
Just backtracking - you don't need to set it up like this - meaning you don't need to ping your server for an assistant - you can have a function that looks them up as well. Even so you need to link your database to remember who the person is. https://cdn.discordapp.com/attachments/1266827885541458065/1268345263555350652/Screenshot_2024-06-13_112316.png?ex=66ac1613&is=66aac493&hm=7e94df51bf89baa810548718ed15addb31721fdb112b5d1484828ace8eaeee8e&
m
So @Chowderr if this is an inbound agent, she receives a call, it calls the Server URL, from that Server URL we can get the assistant ID and the caller's phone number. This works. I use the caller's number to look up the rest of their information (first name, last name, etc) in the address book. Now, how do I get that new, custom information back to the agent so she can address the caller properly? I assumed this was with dynamic variables, using something like {{first_name}} in the system prompt, but I haven't been able to set the dynamic variables. I tried using assistantOverride with the /call endpoint and a PATCH in the assistant/{assistant_id} endpoint but neither work. How do you suggest that I do it?
c
I don't use any ID's (all mine are transient) That information would be already mapped with dynamic values in your prompt.
m
How can I set the values of those dynamic variables?
c
If you are using Make you do it there in your JSON.
m
Thank you to @everyonewho has been helping - here is the code : Server URL set to: https://(our server URL)/incoming_call Python code for incoming_call (abbreviated): @app.route('/incoming_call', methods=['POST']) def incoming_call(): call_event = request.get_json(force=True) message_type = call_event.get('message', {}).get('type', 'unknown') call_status = call_event.get('message', {}).get('status', 'unknown') # Extract assistantId and caller's phone number from the event assistant_id = call_event.get('message', {}).get('call', {}).get('assistantId') caller_id = call_event.get('message', {}).get('call', {}).get('id') # Extract the call ID caller_number = call_event.get('message', {}).get('call', {}).get('customer', {}).get('number') if message_type == 'status-update' and call_status == 'in-progress' and caller_number: try: (not showing this code - this connects to the database, and gets the callerโ€™s information) if result: customer_id = result['customer_id'] first_name = result['first_name'] last_name = result['last_name'] caller_context = result['caller_context'] debug_print(f"Caller identified as {first_name} {last_name} for customer ID {customer_id}") # Prepare the payload for the VAPI /call endpoint payload = { "assistantId": assistant_id, "assistantOverrides": { "variableValues": { "first_name": first_name, "last_name": last_name, "customer_id": customer_id, "caller_context": caller_context } }, "customer": { "number": caller_number }, "phoneNumberId": PHONE_NUMBER_ID } # Log the payload debug_print("Payload being sent to VAPI:", json.dumps(payload, indent=4)) # Make the API call to VAPI api_url = "https://api.vapi.ai/call" headers = { "Content-Type": "application/json", "Authorization": f"Bearer {VAPI_API_KEY}" } response = requests.post(api_url, headers=headers, json=payload)
No, not using Make for this. I do have a custom tool, but that one does something else. This is all being done in the server url endpoint because that's where I obtain the caller_number
you can see, when the call starts, the VAPI agent calls the server url, and in the JSON you can extract the caller's number - "message": { "type": "status-update", "status": "in-progress", "call": { "id": "9ff2571d-d095-4b62-815d-c75221a8be6e", "orgId": "93919d4a-4ea9-4ee6-976d-2c6447c86e24", "createdAt": "2024-07-30T22:49:14.955Z", "updatedAt": "2024-07-30T22:49:14.955Z", "type": "inboundPhoneCall", "status": "ringing", "phoneCallProvider": "twilio", "phoneCallProviderId": "CAb8d54cccc48735a160ba853eb7585883", "phoneCallTransport": "pstn", "phoneNumberId": "a02b6294-63e4-48aa-81dc-f597d27d5cd4", "assistantId": "4a1ff6bf-757d-4e7b-bac5-b4bb728e48ca", "customer": { "number": "+12393516518" }
then that number I use to call my database and get the caller's first name, last name etc
c
To be fair I dont think it matters - this is curl. You need to have 2 responses and they need to go back to the same webhook. This is an example of if the person exist. You need to create one for if it does not as well. https://cdn.discordapp.com/attachments/1266827885541458065/1268448021524250709/message.txt?ex=66ac75c6&is=66ab2446&hm=f9d2446d7dfb8ad02d250f6a2cb8fdf4b58cbdfef4e091bec0f6a97459f8a00a&
m
which API are you calling with this JSON here?
c
call
m
Great. Can I use assistantOverride here?
This is how I was calling it: payload = { "assistantId": assistant_id, "assistantOverrides": { "variableValues": { "first_name": first_name, "last_name": last_name, "customer_id": customer_id, "caller_context": caller_context } }, "customer": { "number": caller_number }, "phoneNumberId": PHONE_NUMBER_ID }
c
This is overide as you don't see an ID ( I also dont use the dashboard at all)
m
but then it starts calling me ๐Ÿ™‚
OK. Yeah everything I have done is through the dashbaord
c
Where are you getting the phone number ID?
m
I get it when the agent calls the Server URL at the outset of the call
c
Dashbaord does not pull any data - plus if its hitting your server you would not have a dashboard assistant. It would be transient. (well you could, but no point)
Ahh sorry - confusing myself with something else. You are correct.
m
{ "message": { "type": "status-update", "status": "in-progress", "call": { "id": "9ff2571d-d095-4b62-815d-c75221a8be6e", "orgId": "93919d4a-4ea9-4ee6-976d-2c6447c86e24", "createdAt": "2024-07-30T22:49:14.955Z", "updatedAt": "2024-07-30T22:49:14.955Z", "type": "inboundPhoneCall", "status": "ringing", "phoneCallProvider": "twilio", "phoneCallProviderId": "CAb8d54cccc48735a160ba853eb7585883", "phoneCallTransport": "pstn", "phoneNumberId": "a02b6294-63e4-48aa-81dc-f597d27d5cd4", "assistantId": "4a1ff6bf-757d-4e7b-bac5-b4bb728e48ca", "customer": { "number": "+12393516518" } }, "phoneNumber": { * "id": "a02b6294-63e4-48aa-81dc-f597d27d5cd4", * "orgId": "93919d4a-4ea9-4ee6-976d-2c6447c86e24", "assistantId": "4a1ff6bf-757d-4e7b-bac5-b4bb728e48ca", "number": "+15128818753", "createdAt": "2024-06-03T18:33:37.417Z", "updatedAt": "2024-07-03T18:34:15.773Z", "stripeSubscriptionId": "sub_1PNfhICRkod4mKy31esQ41DW", "stripeSubscriptionStatus": "active", "stripeSubscriptionCurrentPeriodStart": "2024-07-03T18:33:32.000Z" }, "customer": { "number": "+12393516518" }, "artifact": { "messages": [], "messagesOpenAIFormatted": [] }, "timestamp": "2024-07-30T22:49:15.992Z" } }
I highlighted it above. That's why the server uRL is so useful, it immediately gives you everything you need about the call. I just can't figure out how to write the new dynamic variables back.
so to be clear, I should call the /call end point but how do I use it to set my new dynamic variables like first_name ?
c
I was having a slow moment. I was reading customerID for some reason.
m
np I appreciate any help, I've been stuck on this for weeks ๐Ÿ™‡โ€โ™‚๏ธ
and the weird thing is I have spoken with 4 different people and each one told me a different way to do this
c
Can I call you really quick?
m
and none of them have worked
yeah sure
c
I van only give perspective - I dont use python.
m
sure, even just the workflow of what to do is helpful
c
Just sent you a message.
k
how to set data fetched from server url for inbound calls. can you share the data structure to be used
k
Dear Shubham, Im sharing the response as suggested but same issue 2d539065-d322-46f3-b5d6-f6cfa4d808b0, 6dfd2dbe-625b-4935-b55b-53f716c263b0 { "results": [ { "toolCallId": " call_9jk1", "result": " customer name is teco and address is 123" } ] }
s
mostly like it's from our side can you try making more one call and if exisits create a new ticket for this.
k
Dear Shubam, We tried another call but the same issue remains call id: ddf9952c-e8c8-4964-aa94-9ef58ef47ad5
s
create a new ticket for this.
k
to support@vapi.ai mail only right or is there any other option
12 Views