Examples
CRUD notification (Case modified)
Posted when a case is updated and the subscription includes Case CRUD events:
{
"EventTimestamp": "2026-06-29T14:32:10.123+00:00",
"MessageId": "f1d2c3b4-5a6b-7c8d-9e0f-112233445566",
"Event": "Modify",
"CaseId": 12345,
"Case": {
"Id": 12345,
"Identifier": "S26-001234"
// ...remaining Case fields; matches the REST API Case model
}
}
On a Delete, the Case object is null and only CaseId is present.
Lifecycle event notification (Slide stained)
Posted when a slide is stained and the subscription includes the Slide Stained event:
{
"EventTimestamp": "2026-06-29T14:35:42.987+00:00",
"MessageId": "aabbccdd-eeff-0011-2233-445566778899",
"Event": "Stained",
"SlideId": 98765,
"Slide": {
"Id": 98765,
"Barcode": "SL-98765"
// ...remaining Slide fields; matches the REST API Slide model
}
}
Receiving notifications (C#)
A minimal ASP.NET Core endpoint that accepts a notification, ignores duplicates using
MessageId, and returns quickly:
[ApiController]
[Route("prima/webhooks")]
public class PrimaWebHookController : ControllerBase
{
// Illustrative only. In production, persist processed ids in a durable, shared store.
private static readonly HashSet<Guid> ProcessedMessages = new();
private sealed class WebHookEnvelope
{
public DateTimeOffset EventTimestamp { get; set; }
public Guid MessageId { get; set; }
public string Event { get; set; }
}
[HttpPost]
public async Task<IActionResult> Receive()
{
using var reader = new StreamReader(Request.Body);
var body = await reader.ReadToEndAsync();
var envelope = JsonConvert.DeserializeObject<WebHookEnvelope>(body);
// At-least-once delivery: skip messages we have already handled.
if (!ProcessedMessages.Add(envelope.MessageId))
return Ok();
// Hand `body` off to a background queue, then return promptly so the
// 30-second delivery timeout is never hit.
return Ok();
}
}