Skip to content

Commit 025f128

Browse files
cursoragentgoosewin
andcommitted
Add PHP and Swift server SDKs to documentation
Co-authored-by: dan <[email protected]>
1 parent 9563fd1 commit 025f128

File tree

3 files changed

+278
-0
lines changed

3 files changed

+278
-0
lines changed

fern/docs.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,12 @@ navigation:
757757
- link: Go
758758
href: https://github.com/VapiAI/server-sdk-go
759759
icon: fa-brands fa-golang
760+
- link: PHP
761+
href: https://github.com/VapiAI/server-sdk-php
762+
icon: fa-brands fa-php
763+
- link: Swift
764+
href: https://github.com/VapiAI/server-sdk-swift
765+
icon: fa-brands fa-swift
760766
- page: Ecosystem
761767
path: resources.mdx
762768
icon: fa-light fa-boxes-stacked

fern/quickstart/web.mdx

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,60 @@ Automate outbound calls and handle inbound call processing with server-side SDKs
633633
}
634634
```
635635
</Tab>
636+
637+
<Tab title="PHP">
638+
Install the PHP Server SDK:
639+
640+
```bash
641+
composer require vapi-ai/server-sdk
642+
```
643+
644+
```php
645+
<?php
646+
647+
require_once 'vendor/autoload.php';
648+
649+
use Vapi\VapiClient;
650+
651+
$vapi = new VapiClient(getenv('VAPI_API_KEY'));
652+
653+
// Create an outbound call
654+
$call = $vapi->calls->create([
655+
'phoneNumberId' => 'YOUR_PHONE_NUMBER_ID',
656+
'customer' => ['number' => '+1234567890'],
657+
'assistantId' => 'YOUR_ASSISTANT_ID'
658+
]);
659+
660+
echo "Call created: " . $call->id . "\n";
661+
```
662+
</Tab>
663+
664+
<Tab title="Swift">
665+
Install the Swift Server SDK:
666+
667+
```swift
668+
// Package.swift
669+
dependencies: [
670+
.package(url: "https://github.com/VapiAI/server-sdk-swift", from: "1.0.0")
671+
]
672+
```
673+
674+
```swift
675+
import VapiServerSDK
676+
import Foundation
677+
678+
let vapi = VapiClient(apiKey: ProcessInfo.processInfo.environment["VAPI_API_KEY"]!)
679+
680+
// Create an outbound call
681+
let call = try await vapi.calls.create(
682+
phoneNumberId: "YOUR_PHONE_NUMBER_ID",
683+
customer: Customer(number: "+1234567890"),
684+
assistantId: "YOUR_ASSISTANT_ID"
685+
)
686+
687+
print("Call created: \(call.id)")
688+
```
689+
</Tab>
636690
</Tabs>
637691

638692
### Creating assistants
@@ -778,6 +832,52 @@ Automate outbound calls and handle inbound call processing with server-side SDKs
778832
})
779833
```
780834
</Tab>
835+
836+
<Tab title="PHP">
837+
```php
838+
$assistant = $vapi->assistants->create([
839+
'name' => 'Sales Assistant',
840+
'firstMessage' => "Hi! I'm calling about your interest in our software solutions.",
841+
'model' => [
842+
'provider' => 'openai',
843+
'model' => 'gpt-4o',
844+
'temperature' => 0.7,
845+
'messages' => [[
846+
'role' => 'system',
847+
'content' => 'You are a friendly sales representative. Keep responses under 30 words.'
848+
]]
849+
],
850+
'voice' => [
851+
'provider' => '11labs',
852+
'voiceId' => '21m00Tcm4TlvDq8ikWAM'
853+
]
854+
]);
855+
```
856+
</Tab>
857+
858+
<Tab title="Swift">
859+
```swift
860+
let assistant = try await vapi.assistants.create(
861+
name: "Sales Assistant",
862+
firstMessage: "Hi! I'm calling about your interest in our software solutions.",
863+
model: Model(
864+
provider: "openai",
865+
model: "gpt-4o",
866+
temperature: 0.7,
867+
messages: [
868+
Message(
869+
role: "system",
870+
content: "You are a friendly sales representative. Keep responses under 30 words."
871+
)
872+
]
873+
),
874+
voice: Voice(
875+
provider: "11labs",
876+
voiceId: "21m00Tcm4TlvDq8ikWAM"
877+
)
878+
)
879+
```
880+
</Tab>
781881
</Tabs>
782882

783883
### Bulk operations
@@ -959,6 +1059,66 @@ Run automated call campaigns for sales, surveys, or notifications:
9591059
}
9601060
```
9611061
</Tab>
1062+
1063+
<Tab title="PHP">
1064+
```php
1065+
function runBulkCallCampaign($vapi, $assistantId, $phoneNumberId) {
1066+
$prospects = [
1067+
['number' => '+1234567890', 'name' => 'John Smith'],
1068+
['number' => '+1234567891', 'name' => 'Jane Doe'],
1069+
// ... more prospects
1070+
];
1071+
1072+
$calls = [];
1073+
foreach ($prospects as $prospect) {
1074+
$call = $vapi->calls->create([
1075+
'assistantId' => $assistantId,
1076+
'phoneNumberId' => $phoneNumberId,
1077+
'customer' => $prospect,
1078+
'metadata' => ['campaign' => 'Q1_Sales']
1079+
]);
1080+
$calls[] = $call;
1081+
1082+
// Rate limiting
1083+
sleep(2);
1084+
}
1085+
1086+
return $calls;
1087+
}
1088+
```
1089+
</Tab>
1090+
1091+
<Tab title="Swift">
1092+
```swift
1093+
func runBulkCallCampaign(
1094+
client: VapiClient,
1095+
assistantId: String,
1096+
phoneNumberId: String
1097+
) async throws -> [Call] {
1098+
let prospects = [
1099+
Customer(number: "+1234567890", name: "John Smith"),
1100+
Customer(number: "+1234567891", name: "Jane Doe"),
1101+
// ... more prospects
1102+
]
1103+
1104+
var calls: [Call] = []
1105+
for prospect in prospects {
1106+
let call = try await client.calls.create(
1107+
assistantId: assistantId,
1108+
phoneNumberId: phoneNumberId,
1109+
customer: prospect,
1110+
metadata: ["campaign": "Q1_Sales"]
1111+
)
1112+
calls.append(call)
1113+
1114+
// Rate limiting
1115+
try await Task.sleep(nanoseconds: 2_000_000_000)
1116+
}
1117+
1118+
return calls
1119+
}
1120+
```
1121+
</Tab>
9621122
</Tabs>
9631123

9641124
## Webhook integration
@@ -1251,6 +1411,110 @@ Handle real-time events for both client and server applications:
12511411
}
12521412
```
12531413
</Tab>
1414+
1415+
<Tab title="PHP">
1416+
```php
1417+
<?php
1418+
1419+
header('Content-Type: application/json');
1420+
1421+
$payload = json_decode(file_get_contents('php://input'), true);
1422+
$message = $payload['message'] ?? [];
1423+
1424+
switch ($message['type'] ?? '') {
1425+
case 'status-update':
1426+
$call = $message['call'] ?? [];
1427+
error_log("Call {$call['id']}: {$call['status']}");
1428+
break;
1429+
1430+
case 'transcript':
1431+
error_log("{$message['role']}: {$message['transcript']}");
1432+
break;
1433+
1434+
case 'function-call':
1435+
handleFunctionCall($message);
1436+
exit;
1437+
}
1438+
1439+
echo json_encode(['received' => true]);
1440+
1441+
function handleFunctionCall($message) {
1442+
$functionCall = $message['functionCall'] ?? [];
1443+
$functionName = $functionCall['name'] ?? '';
1444+
1445+
switch ($functionName) {
1446+
case 'lookup_order':
1447+
$orderData = [
1448+
'orderId' => $functionCall['parameters']['orderId'] ?? '',
1449+
'status' => 'shipped'
1450+
];
1451+
echo json_encode(['result' => $orderData]);
1452+
break;
1453+
1454+
default:
1455+
http_response_code(400);
1456+
echo json_encode(['error' => 'Unknown function']);
1457+
}
1458+
}
1459+
```
1460+
</Tab>
1461+
1462+
<Tab title="Swift">
1463+
```swift
1464+
import Vapor
1465+
1466+
func routes(_ app: Application) throws {
1467+
app.post("webhook", "vapi") { req async throws -> Response in
1468+
let payload = try req.content.decode(WebhookPayload.self)
1469+
let message = payload.message
1470+
1471+
switch message.type {
1472+
case "status-update":
1473+
if let call = message.call {
1474+
print("Call \(call.id): \(call.status)")
1475+
}
1476+
case "transcript":
1477+
print("\(message.role ?? ""): \(message.transcript ?? "")")
1478+
case "function-call":
1479+
return try await handleFunctionCall(message)
1480+
default:
1481+
break
1482+
}
1483+
1484+
return try await ["received": true].encodeResponse(for: req)
1485+
}
1486+
}
1487+
1488+
func handleFunctionCall(_ message: WebhookMessage) async throws -> Response {
1489+
guard let functionCall = message.functionCall else {
1490+
throw Abort(.badRequest, reason: "No function call")
1491+
}
1492+
1493+
switch functionCall.name {
1494+
case "lookup_order":
1495+
let orderData = [
1496+
"orderId": functionCall.parameters?["orderId"] ?? "",
1497+
"status": "shipped"
1498+
]
1499+
return try await ["result": orderData].encodeResponse(status: .ok)
1500+
default:
1501+
throw Abort(.badRequest, reason: "Unknown function")
1502+
}
1503+
}
1504+
1505+
struct WebhookPayload: Codable {
1506+
let message: WebhookMessage
1507+
}
1508+
1509+
struct WebhookMessage: Codable {
1510+
let type: String
1511+
let call: Call?
1512+
let role: String?
1513+
let transcript: String?
1514+
let functionCall: FunctionCall?
1515+
}
1516+
```
1517+
</Tab>
12541518
</Tabs>
12551519

12561520
## Next steps
@@ -1278,6 +1542,8 @@ Now that you understand both client and server SDK capabilities:
12781542
- [Ruby SDK GitHub](https://github.com/VapiAI/server-sdk-ruby)
12791543
- [C# SDK GitHub](https://github.com/VapiAI/server-sdk-csharp)
12801544
- [Go SDK GitHub](https://github.com/VapiAI/server-sdk-go)
1545+
- [PHP SDK GitHub](https://github.com/VapiAI/server-sdk-php)
1546+
- [Swift SDK GitHub](https://github.com/VapiAI/server-sdk-swift)
12811547

12821548
**Documentation:**
12831549
- [API Reference](/api-reference)

fern/server-sdks.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,10 @@ The SDKs are open source, and available on GitHub:
2727
<Card title="Vapi Go" icon="fa-brands fa-golang" href="https://github.com/VapiAI/server-sdk-go">
2828
Add a Vapi assistant to your Go application.
2929
</Card>
30+
<Card title="Vapi PHP" icon="fa-brands fa-php" href="https://github.com/VapiAI/server-sdk-php">
31+
Add a Vapi assistant to your PHP application.
32+
</Card>
33+
<Card title="Vapi Swift" icon="fa-brands fa-swift" href="https://github.com/VapiAI/server-sdk-swift">
34+
Add a Vapi assistant to your Swift application.
35+
</Card>
3036
</CardGroup>

0 commit comments

Comments
 (0)