REST API ומפתחות
אימות עם מפתח API, ושיחה מלאה בקוד: יצירה, מעקב, התייעצות, הנחיה וביטול.
מפתחות API
- נכנסים ל־oneli.io/app/connect ובכרטיס מפתחות API לוחצים ליצירת מפתח.
- נותנים שם (1 עד 60 תווים) ובוחרים תוקף: 90 יום (ברירת מחדל), שנה, או ללא תפוגה.
- המפתח, שמתחיל ב־
oli_, מוצג פעם אחת בלבד. שומרים אותו במשתנה סביבה או במנהל סודות, למשלONELI_API_KEY. אצלנו נשמר רק גיבוב שלו.
- ברשימת המפתחות מופיעים ארבעת התווים האחרונים, מתי נוצר, מתי שימש לאחרונה ומתי יפוג. אפשר לבטל מפתח בכל רגע.
- מפתחות נוצרים רק באתר, אחרי התחברות של אדם. אין נקודת קצה ליצירת מפתח עם מפתח.
- מפתח שפג תוקפו או שבוטל מקבל
401 UNAUTHENTICATED. עד 20 מפתחות וסוכנים מחוברים פעילים לחשבון (429 TOO_MANY_AGENTS).
מפתח יכול לעבוד רק עם נקודות הקצה האלה. כל השאר (חיוב, פרופיל, מסלולים, מפתחות) מחזירות 403 INSUFFICIENT_SCOPE:
| שיטה | נתיב |
|---|---|
| GET | /v1/me · /v1/wallet |
| GET | /v1/call-tasks · /v1/call-tasks/:id · /v1/call-tasks/:id/events |
| POST | /v1/call-tasks · /v1/call-tasks/:id/instructions · /v1/call-tasks/:id/cancel |
| POST | /v1/consultations/:id/response |
| GET · PUT · DELETE | /v1/decision-webhook |
| … | הסוכנים שלכם: הגדרות, ידע, שיחות, שיחות יוצאות ווואטסאפ |
כתובת בסיס ובקשות
https://api.oneli.io- כל בקשה עם הכותרת
Authorization: Bearer oli_…. - גוף בקשה ב־JSON עם
Content-Type: application/json, עד 100KB. - זמנים בפורמט ISO 8601 ב־UTC. מספרי טלפון חוזרים בפורמט בינלאומי בלי
+, למשל972501234567. - שגיאות חוזרות כ־
{"error":"CODE","message":"…"}. פירוט בשגיאות ומגבלות.
הדוגמאות בהמשך משתמשות בפונקציית עזר קטנה:
# Every request: the key in the Authorization header, JSON bodies.
export ONELI_API_KEY="oli_..."
export API="https://api.oneli.io"מחזור החיים של שיחה
יוצרים משימה, עוקבים אחרי האירועים עד שהסטטוס סופי (completed, failed, cancelled או expired), עונים להתייעצויות כשהן מגיעות, ואפשר לשלוח הנחיות או לבטל בכל שלב.
1. יצירת משימה
מחליפים את 05XXXXXXXX במספר אמיתי. idempotency_key חובה: אותו מפתח שוב מחזיר את אותה משימה עם created: false ולא יוצר שיחה שנייה. שדות נוספים במדריך העזר.
curl -X POST $API/v1/call-tasks \
-H "Authorization: Bearer $ONELI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"idempotency_key": "order-1234-call",
"to_number": "05XXXXXXXX",
"goal": "לבדוק אם הזמנה 1234 מוכנה לאיסוף ועד מתי אפשר להגיע",
"instructions": "לדבר בקצרה ובנימוס. אם אין תשובה ברורה, לבקש שעה לחזור.",
"constraints": { "max_price_ils": 50 },
"max_duration_s": 180
}'2. מעקב אחרי אירועים
האירועים ממוספרים ברצף. שולחים after עם ה־next_cursor האחרון ומקבלים רק את מה שחדש. קריאה כל 2–3 שניות מספיקה ונשארת הרבה מתחת למגבלת הקצב. כשהקו תפוס או שאין מענה, המשימה חוזרת ל־queued עם אירוע task.retry_scheduled, ולכן ממשיכים לעקוב עד סטטוס סופי.
# Events after the last sequence you have seen (start at 0). Repeat with after=<next_cursor>.
curl "$API/v1/call-tasks/$TASK_ID/events?after=0&limit=100" \
-H "Authorization: Bearer $ONELI_API_KEY"
# The task itself: status, outcome, summary, revision
curl $API/v1/call-tasks/$TASK_ID -H "Authorization: Bearer $ONELI_API_KEY"3. מענה להתייעצות
כשהסוכנת צריכה החלטה, pending_consultation מתמלא (וגם מגיע אירוע consultation.requested). יש רק כמה שניות עד deadline_at, ולכן עונים מהר. התשובה הראשונה קובעת. ask_user תמיד אפשרי: הסוכנת לא מתחייבת וההחלטה חוזרת אליכם. לתשובה אוטומטית בלי polling, ראו Webhook להחלטות.
curl -X POST $API/v1/consultations/con_3d48e1a72832d769/response \
-H "Authorization: Bearer $ONELI_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "decision": "approve", "reason": "בתוך התקציב" }'
# → { "status": "accepted" } (or "expired" / "conflict" with the decision that won)4. הנחיה בזמן שיחה
בשיחה פעילה ההנחיה מגיעה לסוכנת ומשפיעה מהתור הבא שלה. expected_revision מונע התנגשות בין שני שולחים: אם המשימה השתנתה בינתיים מתקבל 409 REVISION_CONFLICT. הנחיה למשימה שעדיין בתור נרשמת ומעלה את הגרסה, אבל לא מועברת לשיחה; כדי לשנות שיחה שעוד לא התחילה, מבטלים ויוצרים משימה חדשה.
# expected_revision = task.revision from GET /v1/call-tasks/:id
curl -X POST $API/v1/call-tasks/$TASK_ID/instructions \
-H "Authorization: Bearer $ONELI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"instruction": "לשאול גם אם אפשר לאסוף מחר אחרי 18:00",
"expected_revision": 1,
"idempotency_key": "order-1234-instr-1"
}'
# → { "command_id": "cmd_…", "revision": 2, "status": "pending" }5. ביטול
משימה בתור מתבטלת מיד. בשיחה פעילה נשלחת בקשת ניתוק, והסטטוס הסופי מגיע באירועים. ביטול של משימה שכבר הסתיימה מחזיר 409 CALL_NOT_ACTIVE. ביטול לא כפוף למגבלת הקצב.
curl -X POST $API/v1/call-tasks/$TASK_ID/cancel \
-H "Authorization: Bearer $ONELI_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "reason": "user_changed_plans" }'
# queued → { "status": "cancelled" } during the call → { "status": "cancel_requested" }הסוכנים שלכם ב־API
כל מה שעוזר הצ׳אט באתר עושה עם הסוכנים שלכם זמין גם במפתח API ובשרת ה־MCP: לבנות ולערוך סוכן, מאגר הידע, לקרוא את השיחות שלו, להפעיל שיחה יוצאת ולנהל את הוואטסאפ שלו. כך אפשר לבנות על OneLi מוצר משלכם: CRM, מערכת לידים או סוכן AI שמפעיל את הסוכן הקולי שלכם. כל נתיב דורש הרשאה (scope); מפתחות וחיבורים חדשים מקבלים את כולן.
| שיטה | נתיב | הרשאה | מה זה עושה |
|---|---|---|---|
| GET | /v1/voice-agents · /v1/voice-agents/:id | agents:read | הסוכנים, וכל ההגדרות של סוכן אחד ומה חסר כדי להפעיל. |
| GET | /v1/voice-agent-templates · /v1/voice-agent-voices · /v1/voice-agent-apps | agents:read | תבניות, כלים, שפות ומודלים; קולות; האפליקציות שחיברתם. |
| POST | /v1/voice-agents | agents:write | סוכן חדש מתבנית (template ו־name). |
| PUT | /v1/voice-agents/:id | agents:write | שומר שם ו־config מלא (קוראים קודם ושולחים את כולו). |
| POST | /v1/voice-agents/:id/deploy · /pause · /playground | agents:write | מפעיל, משהה, או שיחת בדיקה בטקסט. |
| DELETE | /v1/voice-agents/:id | agents:delete | מוחק סוכן: המספר משתחרר והתשלום החודשי שלו מבוטל. |
| GET · POST | /v1/voice-agents/:id/kb · /kb/search | agents:read | מאגר הידע: רשימה וחיפוש כמו בשיחה. |
| POST · PUT · DELETE | /v1/voice-agents/:id/kb · /kb/:item | agents:write | הוספה (טקסט, קישור או התנגדות), עדכון והסרה. |
| GET | /v1/voice-agents/:id/calls · /calls/:task_id | calls:read | השיחות של הסוכן, ושיחה אחת עם התמלול והערות המפקח. |
| POST · GET | /v1/voice-agents/:id/outbound-calls · /outbound-calls/:call | calls:createcalls:read | הסוכן מתקשר למישהו עכשיו (to, variables, Idempotency-Key), וסטטוס השיחה. |
| GET | /v1/voice-agents/:id/whatsapp · /threads · /threads/:tid/messages · /templates · /automations | whatsapp:read | מצב הוואטסאפ של הסוכן, הצ׳אטים וההודעות, התבניות והחוקים. |
| POST | /v1/voice-agents/:id/whatsapp/send · /threads/:tid/messages | whatsapp:send | שליחה מהמספר של הסוכן: to ו־text, או to עם template_id ו־params. |
| POST · PATCH · DELETE | /v1/voice-agents/:id/whatsapp/templates · /automations · /whatsapp | whatsapp:write | תבניות, חוקים ומענה אוטומטי. |
הסוכן מתקשר לליד
הסוכן צריך להיות פעיל. השדות ב־variables ממלאים את ה־{{משתנים}} בהנחיות שלו. אותו Idempotency-Key לא יחייג פעמיים. השיחה המלאה מופיעה בלשונית ״שיחות״ של הסוכן וב־GET …/calls.
curl -X POST https://api.oneli.io/v1/voice-agents/va_…/outbound-calls \
-H "Authorization: Bearer $ONELI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: lead-42" \
-d '{"to":"0521234567","variables":{"name":"Dana","interest":"kitchen renovation"}}'וואטסאפ מהמספר של הסוכן
טקסט חופשי עובר רק בתוך 24 שעות מההודעה האחרונה של אותו אדם; מחוץ לחלון שולחים template_id של תבנית מאושרת עם params. שליחה מה־API משהה את המענה האוטומטי של הסוכן באותו צ׳אט, כמו תשובה שנכתבה באתר.
curl -X POST https://api.oneli.io/v1/voice-agents/va_…/whatsapp/send \
-H "Authorization: Bearer $ONELI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to":"0521234567","text":"Thanks for the call! Here are the details you asked for: …"}'מתכונים לחיבור
הדרך הקצרה לתת לסוכן שלכם לחייג: לעטוף את POST /v1/call-tasks ואת GET /v1/call-tasks/:id בשני כלים. זה עובד עם function calling של OpenAI, עם כלים של LangChain ועם כל מסגרת שמקבלת JSON Schema. מסגרות שתומכות ב־MCP יכולות להתחבר ישירות לשרת ה־MCP עם מפתח ה־API, בלי לכתוב כלים.
// Two tools for your agent. Map them to your framework's tool format.
export const tools = [
{
name: "place_phone_call",
description: "Phone an Israeli number in Hebrew through OneLi to reach a goal. Returns a task_id.",
parameters: {
type: "object",
properties: {
to_number: { type: "string", description: "Israeli number, e.g. 03-1234567 or 050-1234567" },
goal: { type: "string", description: "What the call should achieve (max 500 characters)" },
instructions: { type: "string", description: "How to conduct the call (optional)" },
max_price_ils: { type: "number", description: "Above this price the voice agent consults you" },
},
required: ["to_number", "goal"],
},
},
{
name: "get_call_result",
description: "Status, outcome and summary of a OneLi call task.",
parameters: { type: "object", properties: { task_id: { type: "string" } }, required: ["task_id"] },
},
];
export async function runTool(name, args) {
if (name === "place_phone_call") {
const { task } = await oneli("POST", "/v1/call-tasks", {
idempotency_key: crypto.randomUUID(),
to_number: args.to_number,
goal: args.goal,
instructions: args.instructions,
...(args.max_price_ils != null ? { constraints: { max_price_ils: args.max_price_ils } } : {}),
});
return { task_id: task.id, status: task.status };
}
if (name === "get_call_result") {
const { task, pending_consultation } = await oneli("GET", `/v1/call-tasks/${args.task_id}`);
return { status: task.status, outcome: task.outcome, summary: task.summary, pending_consultation };
}
}ב־n8n, Make ו־Zapier: צומת או מודול HTTP Request עם ההגדרות האלה, ואחריו המתנה וקריאת התוצאה:
Method: POST
URL: https://api.oneli.io/v1/call-tasks
Headers: Authorization: Bearer oli_... (store it as a credential)
Content-Type: application/json
Body: {
"idempotency_key": "lead-{{ id }}",
"to_number": "{{ phone }}",
"goal": "לאשר את פרטי הפנייה ואת מועד הפגישה"
}מדריכים מלאים לכל מסגרת: