Events, Questions and Results
curl --request POST \
--url https://win.oneshotagent.com/v1/compute/{goalId}/eventsimport requests
url = "https://win.oneshotagent.com/v1/compute/{goalId}/events"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://win.oneshotagent.com/v1/compute/{goalId}/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://win.oneshotagent.com/v1/compute/{goalId}/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://win.oneshotagent.com/v1/compute/{goalId}/events"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://win.oneshotagent.com/v1/compute/{goalId}/events")
.asString();require 'uri'
require 'net/http'
url = URI("https://win.oneshotagent.com/v1/compute/{goalId}/events")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyCompute
Events, Questions and Results
Send an event to a case, have a case ask a named person and wait, and receive its result at your own address
POST
/
v1
/
compute
/
{goalId}
/
events
Events, Questions and Results
curl --request POST \
--url https://win.oneshotagent.com/v1/compute/{goalId}/eventsimport requests
url = "https://win.oneshotagent.com/v1/compute/{goalId}/events"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://win.oneshotagent.com/v1/compute/{goalId}/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://win.oneshotagent.com/v1/compute/{goalId}/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://win.oneshotagent.com/v1/compute/{goalId}/events"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://win.oneshotagent.com/v1/compute/{goalId}/events")
.asString();require 'uri'
require 'net/http'
url = URI("https://win.oneshotagent.com/v1/compute/{goalId}/events")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyOverview
Cases are in limited preview. Everything on this page applies to a goal on an account enabled for cases.
Send an event
POST /v1/compute/{goalId}/events with a signed write proof (or an access token).
{ "event_id": "inv-1001", "case_key": "SHIPMENT-8841", "task": "Freight invoice 1001: 1,240.00 USD for shipment 8841" }
event_id: your id for the event. Sending the same id twice is one event.case_key: the case it is about. It opens that case, or wakes it if it is open; a finished case is reopened. A second invoice for the same shipment reaches the same case. Leave it out to send the event to the goal’s root.task: what happened, with everything the case needs.budget_usdc,step_limit: for a case this event opens.
202 with { "target": "case" | "root", "case_key", "outcome": "created" | "already_open" | "reopened" | "sent_to_root" }.
Replies reach the case that asked
An inbound email, text or call result wakes the session that sent the message it answers, and no other goal. Mail that follows nothing a case sent goes to the root of the agent’s newest goal on the loop.A case asks a named person
The case callsask_person with a person’s name and address, a question and a kind:
answer: a reply is the answer. It is written on the case’s record with who, when,via: "reply"and the message it came from (inbound_email:<id>).approval: anything that releases an action (an amount, a booking, a merge). The person is sent a signed, single-use link that expires, which opens a page showing what is being approved and two buttons. Only the click counts. A reply to the same email, even one that says “approved”, is told to the case and releases nothing. The click is written on the record with who, when,via: "link"and what the person was shown (shown,shown_hash).
chase_after_seconds, up to three reminders) and has a deadline (deadline_seconds, default 7 days) at which the case is told to escalate. A used, expired or altered link is refused.
Results out
Give the goal an address when you create it:{ "params": { "result_webhook_url": "https://example.com/oneshot/results" } }
deliver_result, and OneShot POSTs it to that address:
{ "event": "case.result", "goal_id": "…", "case": "SHIPMENT-8841", "result": { "amount_usd": 1180 }, "approval": { "ask_id": "…", "who": "Rae", "when": "…", "via": "link" }, "delivery_id": "…", "attempt": 1 }
X-OneShot-Signature (t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<body>">). Read the secret at GET /v1/compute/{goalId}/result-webhook.
If the case asked for an approval, only a result equal to the approved one is sent; anything else is withheld. A failed delivery is retried with a growing delay and gives up after six attempts. Every attempt shows on the case.
Read a case
GET /v1/compute/{goalId}/cases/{key} returns the case’s record, decisions, asks (each with status, chases, deadline_at, escalated_at) and deliveries (each with status, attempts, last_error, next_attempt_at).