What is a WebHook In?
A WebHook In (also known as incoming WebHook) allows data within Orca Scan to be updated by an external system as events happen.
How does a WebHook In work?
Every Orca sheet has its own unique WebHook In URL; external systems can send data to this URL to add, update or delete a row within a sheet.
Data must be sent as an HTTP POST in JSON format and contain a ___orca_action
key, for example:
Add a new row
The following example adds a new row to a sheet, setting the value of Barcode, Name, Quantity and Description:
{
"___orca_action": "add",
"Barcode": "0123456789",
"Name": "New 1",
"Quantity": 12,
"Description": "Add new row example"
}
Update an existing row
The following example updates an existing row in a sheet, setting the Quantity to 75 where the Barcode = 8511207696421
{
"___orca_action": "update",
"Barcode": "8511207696421",
"Quantity": 75
}
Note: if the row to be updated does not exist, a new row is created.
Delete a row
The following example deletes a row from a sheet where Barcode = 8511207696421
{
"___orca_action": "delete",
"Barcode": "8511207696421"
}
Apply multiple changes with one request
The following example adds two rows and deletes one, with one request:
[
{
"___orca_action": "add",
"Barcode": "0123456789",
"Name": "New 1",
"Quantity": 12,
"Description": "Add new row example"
},
{
"___orca_action": "add",
"Barcode": "9876543210",
"Name": "New 2",
"Quantity": 19
},
{
"___orca_action": "delete",
"Barcode": "8511207696421",
}
]
How do I create a WebHook In?
In order to create a Webhook In, you only need to send a POST request to the URL that you have been given with the action desired and the data of the object in JSON format as explained above.
As can be observed, in the following example snippets you will need to access the /trigger-webhook-in
route on your server in order to launch the request.
app.get('/trigger-webhook-in', function(request, response) {
// the following example adds a new row to a sheet
const json = JSON.stringify(
{
"___orca_action": "add",
"Barcode": "0123456789",
"Name": "New 1",
"Quantity": 12,
"Description": "Add new row example"
}
);
// TODO: change url to https://api.orcascan.com/sheets/{id}
const res = await axios.post("https://httpbin.org/post", json, {
headers: {
// Overwrite Axios's automatically set Content-Type
'Content-Type': 'application/json'
}
});
response.sendStatus(200);
});
[ApiController]
[Route("/trigger-webhook-in")]
public class OrcaWebHookInDotNet : ControllerBase
{
[HttpGet]
public async Task<OkResult> WebHookTrigger()
{
// the following example adds a new row to a sheet
// setting the value of Barcode, Name, Quantity and Description
// TODO: change url to https://api.orcascan.com/sheets/{id}
string url = "https://httpbin.org/post";
string json = "{\"___orca_action\":\"add\",\"___orca_sheet_name\":\"Sheet1\",\"Barcode\":\"123456789\",\"Name\":\"Test\",\"Quantity\":\"1\",\"Description\":\"Test\"}";
// send post request
var client = new HttpClient();
var content = new StringContent(json, Encoding.UTF8, "application/json");
var result = await client.PostAsync(url, content);
// if response ok print it
if (result.IsSuccessStatusCode)
{
var response = await result.Content.ReadAsStringAsync();
Console.WriteLine(response);
}
return Ok();
}
}
func webHookInHandler(w http.ResponseWriter, r *http.Request) {
values := map[string]string{
"___orca_action": "add",
"Barcode": "0123456789",
"Name": "New 1",
"Quantity": "12",
"Description": "Add new row example",
}
jsonValue, _ := json.Marshal(values)
// The following example adds a new row to a sheet
// setting the value of Barcode, Name, Quantity and Description
// TODO: change url to https://api.orcascan.com/sheets/{id}
response, err := http.Post("https://httpbin.org/post", "application/json", bytes.NewBuffer(jsonValue))
if err != nil {
// read response error
fmt.Println(err)
}
else {
// read response body
body, _ := ioutil.ReadAll(response.Body)
data := map[string]string{}
jsonErr := json.Unmarshal([]byte(body), &data)
if jsonErr != nil {
return
}
fmt.Println(data)
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
return
}
@app.route('/trigger-webhook-in', methods=['GET'])
def trigger_webhook_in():
# the following example adds a new row to a sheet
# setting the value of Barcode, Name, Quantity and Description
# TODO: change url to https://api.orcascan.com/sheets/{id}
response = requests.post('https://httpbin.org/post', json={
"___orca_action": "add",
"Barcode": "0123456712",
"Name": "New 1",
"Quantity": 12,
"Description": "Add new row example"
})
if response.ok:
print(response.content)
return "ok"
if (preg_match('/trigger-webhook-in$/', $_SERVER["REQUEST_URI"])) {
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
// The following example adds a new row to a sheet
// setting the value of Barcode, Name, Quantity and Description
$data = array(
"___orca_action" => "update",
"barcode" => "0123456789",
"Name" => "New 1",
"Quantity" => 12,
"Description" => "Add new row example"
);
// TODO: change url to https://api.orcascan.com/sheets/{id}
$url = 'https://httpbin.org/post';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen(json_encode($data))
));
$response = curl_exec($ch);
curl_close($ch);
echo $response;
}
}
@RequestMapping(
value = "/trigger-webhook-in",
method = RequestMethod.GET)
String triggerWebhookIn() throws Exception {
RestTemplate restTemplate = new RestTemplate();
// The following example adds a new row to a sheet
// setting the value of Barcode, Name, Quantity and Description
// TODO: change url to https://api.orcascan.com/sheets/{id}
String url = "https://httpbin.org/post";
JSONObject json = new JSONObject();
json.put("___orca_action", "add");
json.put("Barcode", "0123456789");
json.put("Name", "New 1");
json.put("Quantity", 12);
json.put("Description", "Add new row example");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(json.toJSONString(), headers);
String answer = restTemplate.postForObject(url, entity, String.class);
System.out.println(answer);
return "ok";
}
A fully working version for all programming languages can be found on GitHub.
How do I get the WebHook In URL for my sheet?
To get the unique WebHook In URL for a sheet, simply:
1. Select a sheet
Select the relevant sheet or create a new one
2. Open Integrations
Open sheet Integrations from the toolbar
3. Activate WebHook In
Activate WebHook In by clicking the on the toggle.
4. Copy WebHook In URL
Click copy to the right of the WebHook In URL to copy the value to your clipboard.
You can now share this URL to allow developers/systems to update your barcode data.
Security
You can secure your WebHook In by providing a secret. When set, the HTTP Header orca-secret
must be provided with each request. Requests that do not match the secret set on your sheet will be rejected with a 403 Forbidden.
WebHook In FAQs
How do I ensure updates happen in the correct sequence?
A Web Hook In request will respond with a HTTP status code 200 once the update has been applied, wait for this response before sending the next request.
How many rows can I send in one request?
You can send a maximum of 100 rows in each request, any more than this will result in a HTTP 400 Bad Request error.
What is the rate limit?
You can send a maximum of 15 requests per second, exceeding this limit will result in a HTTP 503 Service Unavailable response.
WebHook questions?
We’re happy to help troubleshoot any issues you might have connecting Orca Scan to your system, simply chat with us live or drop us an email.
What error messages does the WebHook in return?
The following HTTP status codes indicate the success or failure of a request:
Status | Error | Message |
---|---|---|
200 |
Ok | Request successful |
400 |
Bad request | Invalid row data |
400 |
Bad request | Too many rows; requests are limited to 100 rows |
400 |
Bad request | Invalid row data; missing Barcode value |
400 |
Bad request | Invalid ___orca_action ; expected add , update or delete |
400 |
Bad request | Exceeded row limit, please upgrade |
403 |
Forbidden | You do not have permission to access this resource |
404 |
Not found | The requested URL was not found |
All HTTP errors include a JSON body structured as follows:
{
"status": 400,
"error": "Bad request",
"message": "Too many rows; requests are limited to 100 rows"
}