Developer documentation
Fatoorah API with .NET
Use a named HttpClient, keep the bearer credential in managed configuration, send a stable idempotency key, and store the returned request identity for logs, webhooks, and support.
Implementation guide
What the integration should preserve.
- 01
Use IHttpClientFactory rather than creating a client for every request.
- 02
Keep credentials in server-side configuration protected by the deployment platform.
- 03
Apply retries only to explicitly safe transport failures.
- 04
Read the structured error response before deciding an operation can be repeated.
- 05
Verify webhook signatures before deserializing into domain events.
Relevant paths
POST /v1/zatca/invoices/generate/simplifiedPOST /v1/webhook-endpointsExample
using var request = new HttpRequestMessage(
HttpMethod.Post,
"/v1/zatca/invoices/generate/simplified"
);
request.Headers.Authorization = new("Bearer", options.ApiKey);
request.Headers.Add("Idempotency-Key", "invoice-demo-001");
var body = """
{
"organization_id": "$TECHNOMINDS_ORGANIZATION_ID",
"egs_unit_id": null,
"taxpayer_profile_id": null,
"tax_calculation_mode": "TECHNOMINDS_CALCULATES",
"requested_invoice_type": "SIMPLIFIED_TAX_INVOICE",
"seller": {
"legal_name": "Synthetic Najd Retail",
"vat_number": "310000000000003",
"commercial_registration": null,
"address": null,
"branch": "Riyadh",
"additional_identifiers": []
},
"buyer": {
"legal_name": null,
"vat_number": null,
"commercial_registration": null,
"address": null,
"additional_identifiers": [],
"buyer_type": "individual"
},
"supply": {
"supply_date": "2026-08-10",
"end_date": null,
"purchase_order_reference": null,
"contract_reference": null,
"delivery_reference": null,
"payment_terms": null,
"payment_method": "card"
},
"line_items": [
{
"line_id": "line-1",
"name_ar": "عنصر تجريبي",
"name_en": "Synthetic sandbox item",
"description": "Fictional developer fixture",
"quantity": 1,
"unit_code": "PCE",
"unit_price": 10000,
"discounts": [],
"charges": [],
"tax_category": "standard_rated",
"tax_rate": 15,
"tax_exemption_reason": null
}
],
"notes": {}
}
""".Replace("$TECHNOMINDS_ORGANIZATION_ID", options.OrganizationId);
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request, cancellationToken);
response.EnsureSuccessStatusCode();Continue reading