// The Food Integrity Project API client, generated from the OpenAPI document (API 2.0.0).
// Don't edit: run `npm run api:clients` in the FIP-OS repository. Guides: https://api.foodintegrityproject.org/docs
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
namespace FoodIntegrityProject.Api
{
/// An error answer, with its problem details (code, title, detail, field).
public class ApiException : Exception
{
public int Status { get; }
public JsonElement Problem { get; }
public string? Code => Problem.ValueKind == JsonValueKind.Object && Problem.TryGetProperty("code", out var c) ? c.GetString() : null;
public ApiException(int status, JsonElement problem, string message) : base(message) { Status = status; Problem = problem; }
}
/// Options every operation takes.
public class CallOptions
{
/// Sent as Idempotency-Key on a write, so retrying it is safe.
public string? IdempotencyKey { get; set; }
/// The ETag from your last GET: the change applies only if the record hasn't changed since.
public string? IfMatch { get; set; }
}
public class FoodIntegrityProjectApi
{
private readonly HttpClient http;
private readonly string baseUrl;
public string? Token { get; set; }
/// Production by default; https://api.foodintegrityproject.org/sandbox/v2 for the sandbox.
public FoodIntegrityProjectApi(string? token = null, string baseUrl = "https://api.foodintegrityproject.org/v2", HttpClient? http = null)
{
Token = token;
this.baseUrl = baseUrl.TrimEnd('/');
this.http = http ?? new HttpClient();
}
/// Gets a token for an organization's key (client credentials with its secret) and uses it from then on.
public async Task SignInAsync(string clientId, string clientSecret, string? scope = null, CancellationToken ct = default)
{
var form = new Dictionary { ["grant_type"] = "client_credentials", ["client_id"] = clientId, ["client_secret"] = clientSecret };
if (scope != null) form["scope"] = scope;
using var res = await http.PostAsync(baseUrl + "/oauth/token", new FormUrlEncodedContent(form), ct);
var json = JsonDocument.Parse(await res.Content.ReadAsStringAsync(ct)).RootElement.Clone();
if (!res.IsSuccessStatusCode) throw new ApiException((int)res.StatusCode, json, json.TryGetProperty("error_description", out var d) ? d.GetString() ?? "Sign-in failed" : "Sign-in failed");
Token = json.GetProperty("access_token").GetString();
return json;
}
public async Task RequestAsync(string method, string path, IDictionary? query = null, object? body = null, CallOptions? options = null, CancellationToken ct = default)
{
var url = baseUrl + path;
var q = query?.Where(kv => kv.Value != null).Select(kv => Uri.EscapeDataString(kv.Key) + "=" + Uri.EscapeDataString(kv.Value is bool b ? (b ? "true" : "false") : Convert.ToString(kv.Value, System.Globalization.CultureInfo.InvariantCulture) ?? "")).ToList();
if (q != null && q.Count > 0) url += "?" + string.Join("&", q);
using var req = new HttpRequestMessage(new HttpMethod(method), url);
req.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (Token != null) req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", Token);
if (options?.IdempotencyKey != null) req.Headers.Add("Idempotency-Key", options.IdempotencyKey);
if (options?.IfMatch != null) req.Headers.TryAddWithoutValidation("If-Match", options.IfMatch);
if (body != null) req.Content = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
using var res = await http.SendAsync(req, ct);
var text = await res.Content.ReadAsStringAsync(ct);
var json = string.IsNullOrEmpty(text) ? default : JsonDocument.Parse(text).RootElement.Clone();
if (!res.IsSuccessStatusCode)
{
var message = json.ValueKind == JsonValueKind.Object && json.TryGetProperty("detail", out var d) ? d.GetString() : null;
throw new ApiException((int)res.StatusCode, json, message ?? $"HTTP {(int)res.StatusCode}");
}
return json;
}
// Writes
/// Add a country of origin.
public Task AddCountryOfOriginAsync(string id, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/products/{Uri.EscapeDataString(id)}/countries-of-origin", null, body, options, ct);
/// Send up to 500 operations.
public Task BatchAsync(object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/batch", null, body, options, ct);
/// Cancel a verification.
public Task CancelVerificationAsync(string @ref, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/verifications/{Uri.EscapeDataString(@ref)}/cancel", null, null, options, ct);
/// Add a brand to a client.
public Task CreateBrandAsync(object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/brands", null, body, options, ct);
// Verification management
/// Make a certificate PDF.
public Task CreateCertificatePdfAsync(object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/certificates/pdf", null, body, options, ct);
// Writes
/// Send a client application.
public Task CreateClientAsync(object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/clients", null, body, options, ct);
/// Register a facility.
public Task CreateFacilityAsync(object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/facilities", null, body, options, ct);
/// Add a package.
public Task CreatePackageAsync(string id, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/products/{Uri.EscapeDataString(id)}/packages", null, body, options, ct);
/// Add a verification.
public Task CreateVerificationAsync(string id, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/products/{Uri.EscapeDataString(id)}/verifications", null, body, options, ct);
// Webhooks
/// Add a webhook.
public Task CreateWebhookAsync(object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/webhooks", null, body, options, ct);
/// Remove a webhook.
public Task DeleteWebhookAsync(string id, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("DELETE", $"/webhooks/{Uri.EscapeDataString(id)}", null, null, options, ct);
// Catalog
/// Get a brand.
public Task GetBrandAsync(string number, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/catalog/brands/{Uri.EscapeDataString(number)}", null, null, options, ct);
// Verification management
/// Get a certificate.
public Task GetCertificateAsync(string number, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/certificates/{Uri.EscapeDataString(number)}", null, null, options, ct);
/// Get a certificate job.
public Task GetCertificatePdfAsync(string job, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/certificates/pdf/{Uri.EscapeDataString(job)}", null, null, options, ct);
/// Get a client.
public Task GetClientAsync(string id, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/clients/{Uri.EscapeDataString(id)}", null, null, options, ct);
// Prospects
/// Demand for your products.
public Task GetDemandAsync(string? days = null, string? ta = null, string? limit = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/demand", new Dictionary { ["days"] = days, ["ta"] = ta, ["limit"] = limit }, null, options, ct);
// Verification management
/// Get a facility.
public Task GetFacilityAsync(string id, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/facilities/{Uri.EscapeDataString(id)}", null, null, options, ct);
// Signing in
/// Who this token is.
public Task GetMeAsync(CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/me", null, null, options, ct);
// Prospects
/// Get an opportunity.
public Task GetOpportunityAsync(string id, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/opportunities/{Uri.EscapeDataString(id)}", null, null, options, ct);
// Catalog
/// Get a listed product.
public Task GetProductAsync(string id, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/catalog/products/{Uri.EscapeDataString(id)}", null, null, options, ct);
// Verification management
/// Get a brand.
public Task GetTaBrandAsync(string number, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/brands/{Uri.EscapeDataString(number)}", null, null, options, ct);
/// Get a product.
public Task GetTaProductAsync(string id, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/products/{Uri.EscapeDataString(id)}", null, null, options, ct);
/// Get a verification.
public Task GetVerificationAsync(string @ref, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/verifications/{Uri.EscapeDataString(@ref)}", null, null, options, ct);
/// Get one facility on a verification.
public Task GetVerificationFacilityAsync(string @ref, string facilityId, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/verifications/{Uri.EscapeDataString(@ref)}/facilities/{Uri.EscapeDataString(facilityId)}", null, null, options, ct);
// Webhooks
/// Get a webhook.
public Task GetWebhookAsync(string id, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/webhooks/{Uri.EscapeDataString(id)}", null, null, options, ct);
// Writes
/// Put all a client's products on hold.
public Task HoldAllForClientAsync(string id, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/clients/{Uri.EscapeDataString(id)}/hold-all", null, body, options, ct);
/// Put a verification on hold.
public Task HoldVerificationAsync(string @ref, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/verifications/{Uri.EscapeDataString(@ref)}/hold", null, body, options, ct);
// Catalog
/// List brands with listed products.
public Task ListBrandsAsync(string? q = null, string? limit = null, string? cursor = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/catalog/brands", new Dictionary { ["q"] = q, ["limit"] = limit, ["cursor"] = cursor }, null, options, ct);
/// List categories by certificate group.
public Task ListCategoriesAsync(CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/catalog/categories", null, null, options, ct);
// Verification management
/// List your certificates.
public Task ListCertificatesAsync(string? program = null, string? listed = null, string? updatedSince = null, string? ta = null, string? limit = null, string? cursor = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/certificates", new Dictionary { ["program"] = program, ["listed"] = listed, ["updated_since"] = updatedSince, ["ta"] = ta, ["limit"] = limit, ["cursor"] = cursor }, null, options, ct);
// Catalog
/// What changed in the listing.
public Task ListChangesAsync(string? since = null, string? limit = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/catalog/changes", new Dictionary { ["since"] = since, ["limit"] = limit }, null, options, ct);
// Verification management
/// List your clients.
public Task ListClientsAsync(string? status = null, string? program = null, string? q = null, string? updatedSince = null, string? ta = null, string? limit = null, string? cursor = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/clients", new Dictionary { ["status"] = status, ["program"] = program, ["q"] = q, ["updated_since"] = updatedSince, ["ta"] = ta, ["limit"] = limit, ["cursor"] = cursor }, null, options, ct);
/// List a product's countries of origin.
public Task ListCountriesOfOriginAsync(string id, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/products/{Uri.EscapeDataString(id)}/countries-of-origin", null, null, options, ct);
// Webhooks
/// List a webhook's deliveries.
public Task ListDeliveriesAsync(string id, string? limit = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/webhooks/{Uri.EscapeDataString(id)}/deliveries", new Dictionary { ["limit"] = limit }, null, options, ct);
/// List event types.
public Task ListEventTypesAsync(CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/event-types", null, null, options, ct);
// Verification management
/// List facilities on your verifications.
public Task ListFacilitiesAsync(string? q = null, string? ta = null, string? limit = null, string? cursor = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/facilities", new Dictionary { ["q"] = q, ["ta"] = ta, ["limit"] = limit, ["cursor"] = cursor }, null, options, ct);
// Prospects
/// List opportunities shared with you.
public Task ListOpportunitiesAsync(string? stage = null, string? updatedSince = null, string? ta = null, string? limit = null, string? cursor = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/opportunities", new Dictionary { ["stage"] = stage, ["updated_since"] = updatedSince, ["ta"] = ta, ["limit"] = limit, ["cursor"] = cursor }, null, options, ct);
// Verification management
/// List a product's packages.
public Task ListPackagesAsync(string id, string? includeRemoved = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/products/{Uri.EscapeDataString(id)}/packages", new Dictionary { ["include_removed"] = includeRemoved }, null, options, ct);
// Catalog
/// List and search listed products.
public Task ListProductsAsync(string? q = null, string? gtin = null, string? certificate = null, string? brandNumber = null, string? program = null, string? category = null, string? updatedSince = null, string? limit = null, string? cursor = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/catalog/products", new Dictionary { ["q"] = q, ["gtin"] = gtin, ["certificate"] = certificate, ["brand_number"] = brandNumber, ["program"] = program, ["category"] = category, ["updated_since"] = updatedSince, ["limit"] = limit, ["cursor"] = cursor }, null, options, ct);
// Verification management
/// List brands on your products.
public Task ListTaBrandsAsync(string? q = null, string? ta = null, string? limit = null, string? cursor = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/brands", new Dictionary { ["q"] = q, ["ta"] = ta, ["limit"] = limit, ["cursor"] = cursor }, null, options, ct);
/// List your products.
public Task ListTaProductsAsync(string? q = null, string? brandNumber = null, string? participant = null, string? program = null, string? updatedSince = null, string? ta = null, string? limit = null, string? cursor = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/products", new Dictionary { ["q"] = q, ["brand_number"] = brandNumber, ["participant"] = participant, ["program"] = program, ["updated_since"] = updatedSince, ["ta"] = ta, ["limit"] = limit, ["cursor"] = cursor }, null, options, ct);
/// List a verification's facilities.
public Task ListVerificationFacilitiesAsync(string @ref, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/verifications/{Uri.EscapeDataString(@ref)}/facilities", null, null, options, ct);
/// List your verifications.
public Task ListVerificationsAsync(string? status = null, string? program = null, string? product = null, string? current = null, string? updatedSince = null, string? ta = null, string? limit = null, string? cursor = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/verifications", new Dictionary { ["status"] = status, ["program"] = program, ["product"] = product, ["current"] = current, ["updated_since"] = updatedSince, ["ta"] = ta, ["limit"] = limit, ["cursor"] = cursor }, null, options, ct);
// Webhooks
/// List your webhooks.
public Task ListWebhooksAsync(CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/webhooks", null, null, options, ct);
// Catalog
/// Verify a product.
public Task LookupAsync(string? gtin = null, string? certificate = null, string? product = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("GET", $"/catalog/lookup", new Dictionary { ["gtin"] = gtin, ["certificate"] = certificate, ["product"] = product }, null, options, ct);
// Writes
/// Change a client.
public Task PatchClientAsync(string id, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("PATCH", $"/clients/{Uri.EscapeDataString(id)}", null, body, options, ct);
/// Change a package.
public Task PatchPackageAsync(string id, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("PATCH", $"/packages/{Uri.EscapeDataString(id)}", null, body, options, ct);
/// Change a product.
public Task PatchProductAsync(string id, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("PATCH", $"/products/{Uri.EscapeDataString(id)}", null, body, options, ct);
/// Change a verification's details.
public Task PatchVerificationAsync(string @ref, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("PATCH", $"/verifications/{Uri.EscapeDataString(@ref)}", null, body, options, ct);
/// Set a client's contact.
public Task PutClientContactAsync(string id, string role, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("PUT", $"/clients/{Uri.EscapeDataString(id)}/contacts/{Uri.EscapeDataString(role)}", null, body, options, ct);
/// Add or update a product.
public Task PutProductAsync(string id, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("PUT", $"/products/{Uri.EscapeDataString(id)}", null, body, options, ct);
/// Add or update a facility on a verification.
public Task PutVerificationFacilityAsync(string @ref, string facilityId, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("PUT", $"/verifications/{Uri.EscapeDataString(@ref)}/facilities/{Uri.EscapeDataString(facilityId)}", null, body, options, ct);
/// Release a verification from hold.
public Task ReleaseVerificationAsync(string @ref, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/verifications/{Uri.EscapeDataString(@ref)}/release", null, null, options, ct);
/// Clear a client's contact.
public Task RemoveClientContactAsync(string id, string role, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("DELETE", $"/clients/{Uri.EscapeDataString(id)}/contacts/{Uri.EscapeDataString(role)}", null, null, options, ct);
/// Remove a package.
public Task RemovePackageAsync(string id, string? reason = null, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("DELETE", $"/packages/{Uri.EscapeDataString(id)}", new Dictionary { ["reason"] = reason }, null, options, ct);
/// Remove a facility from a verification.
public Task RemoveVerificationFacilityAsync(string @ref, string facilityId, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("DELETE", $"/verifications/{Uri.EscapeDataString(@ref)}/facilities/{Uri.EscapeDataString(facilityId)}", null, null, options, ct);
/// Renew a verification.
public Task RenewVerificationAsync(string @ref, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/verifications/{Uri.EscapeDataString(@ref)}/renew", null, body, options, ct);
// Webhooks
/// Send a delivery again.
public Task ReplayDeliveryAsync(string id, string delivery, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/webhooks/{Uri.EscapeDataString(id)}/deliveries/{Uri.EscapeDataString(delivery)}/replay", null, null, options, ct);
/// Rotate a webhook's secret.
public Task RotateWebhookSecretAsync(string id, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/webhooks/{Uri.EscapeDataString(id)}/rotate-secret", null, null, options, ct);
// Writes
/// Terminate a verification.
public Task TerminateVerificationAsync(string @ref, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/verifications/{Uri.EscapeDataString(@ref)}/terminate", null, body, options, ct);
// Webhooks
/// Send a test.
public Task TestWebhookAsync(string id, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/webhooks/{Uri.EscapeDataString(id)}/test", null, null, options, ct);
// Writes
/// Mark a verification transferred.
public Task TransferVerificationAsync(string @ref, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/verifications/{Uri.EscapeDataString(@ref)}/transfer", null, body, options, ct);
/// Withdraw all a client's products.
public Task WithdrawAllForClientAsync(string id, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/clients/{Uri.EscapeDataString(id)}/withdraw-all", null, body, options, ct);
/// Withdraw a client.
public Task WithdrawClientAsync(string id, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/clients/{Uri.EscapeDataString(id)}/withdraw", null, body, options, ct);
/// Withdraw a verification.
public Task WithdrawVerificationAsync(string @ref, object body, CallOptions? options = null, CancellationToken ct = default) =>
RequestAsync("POST", $"/verifications/{Uri.EscapeDataString(@ref)}/withdraw", null, body, options, ct);
}
}