OpenAPI
The API is described by an OpenAPI document: every operation, what it takes and what it answers with, with descriptions. Get it from
https://saas.parametriq.co.uk/openapi.json
No API key is needed for the document itself, only for the operations it describes. It is OpenAPI 3.1, and gives
https://saas.parametriq.co.uk as the server, so a client generated from it calls the service there. Its security
scheme, ApiKey, is your key in the X-API-KEY header (Using your API Key).
Use it to:
- generate a client in your own language, with a class for each request and response and a method for each operation (below);
- try the API in a tool that reads OpenAPI documents, such as Postman, Insomnia, Bruno or Swagger UI: import the
address above, set the
X-API-KEYheader, and send requests; - check what the API takes: the document is the full reference, as the API pages are its guide.
Generating a client with Kiota
Kiota is Microsoft's client generator. It makes clients for C#, Go, Java, PHP, Python, Ruby and TypeScript from an OpenAPI document. For C#:
dotnet tool install --global Microsoft.OpenApi.Kiota
dotnet new console -n PiqDemo
cd PiqDemo
dotnet add package Microsoft.Kiota.Bundle
kiota generate -l CSharp -c PiqClient -n Piq.Client -d https://saas.parametriq.co.uk/openapi.json -o ./Client
That makes a PiqClient class in the Client folder, with a request builder for each operation (client.Inputs,
client.Measure, client.Export["pdf"] …) and a class for each request and response (TemplateRequest,
DrawingRequest, MeasureResponse …). Then:
using Microsoft.Kiota.Abstractions.Authentication;
using Microsoft.Kiota.Abstractions.Serialization;
using Microsoft.Kiota.Http.HttpClientLibrary;
using Piq.Client;
using Piq.Client.Models;
// the key goes in the X-API-KEY header of every request
var key = Environment.GetEnvironmentVariable("PIQ_API_KEY") ?? throw new InvalidOperationException("Set PIQ_API_KEY.");
var auth = new ApiKeyAuthenticationProvider(key, "X-API-KEY", ApiKeyAuthenticationProvider.KeyLocation.Header);
var adapter = new HttpClientRequestAdapter(auth);
if (Environment.GetEnvironmentVariable("PIQ_URL") is { } url) adapter.BaseUrl = url;
var client = new PiqClient(adapter);
const string template = "L=400,\"Length\"\nW=300,\"Width\"\nP1=[L,0]\nP2=[L,W]\nP3=[0,W]\nPOLYLINE @1,[P0,P1,P2,P3],TRUE,0";
// the template's labelled variables
var inputs = await client.Inputs.PostAsync(new TemplateRequest { Template = template });
foreach (var input in inputs!.Inputs!) Console.WriteLine($"{input.Name}: {input.Label} ({input.Kind})");
// values for them: any of the template's labelled variables, by name
var values = new DrawingRequest_values { AdditionalData = { ["L"] = 500, ["W"] = 250 } };
// measured
var measured = await client.Measure.PostAsync(new DrawingRequest { Template = template, Values = values });
Console.WriteLine($"Size: {measured!.Width} x {measured.Height}");
// exported as a PDF
var pdf = await client.Export["pdf"].PostAsync(new ExportRequest
{
Template = template, Values = new ExportRequest_values { AdditionalData = values.AdditionalData }
});
await using (var file = File.Create("box.pdf")) await pdf!.CopyToAsync(file);
Console.WriteLine("Saved box.pdf");
// a value that can't be used: refused, saying why
try
{
await client.Measure.PostAsync(new DrawingRequest
{
Template = template, Values = new DrawingRequest_values { AdditionalData = { ["L"] = "long" } }
});
}
catch (ValidationProblemDetails problem)
{
Console.WriteLine($"{problem.Title} {problem.Detail}");
// what is wrong, by the value it is about: each a list of messages
foreach (var (name, messages) in problem.Errors?.AdditionalData ?? new Dictionary<string, object>())
if (messages is UntypedArray list)
Console.WriteLine($" {name}: {string.Join(" ", list.GetValue().OfType<UntypedString>().Select(m => m.GetValue()))}");
}
How it works:
- The key.
ApiKeyAuthenticationProviderputs your key in theX-API-KEYheader of every request (over https only). - Values. A template's labelled variables are its own, so
valueshas no fixed fields: give them inAdditionalData, by name. - Files.
Export(andPreview) answer with aStream: the file's bytes, whatever its format. - Errors. A request that is refused throws the problem description: a
ValidationProblemDetails(400), with what is wrong with which value inErrors, or aProblemDetailsfor the others (404,409,422,502…).
Run kiota generate again when the API changes, to bring the client up to date. For another language, give its name
with -l (Go, Java, PHP, Python, Ruby, TypeScript) and add that language's Kiota packages, which
kiota info -l <language> lists.
Other generators
Any OpenAPI generator can be given the same address:
- NSwag (C# and TypeScript):
nswag openapi2csclient /input:https://saas.parametriq.co.uk/openapi.json /output:PiqClient.cs /namespace:Piq.Client. - OpenAPI Generator (most languages):
npx @openapitools/openapi-generator-cli generate -i https://saas.parametriq.co.uk/openapi.json -g python -o piq-client, with-gnaming the language (typescript-fetch,java,go,php,ruby,csharp…).
A generated client needs your key in the X-API-KEY header, as every request does: each generator has its own way of
giving it (an API key setting, or a default header).
If you would rather not generate anything, the API is plain HTTPS and JSON: see the Clients for a complete example in each of several languages, using only their own HTTP clients.
See also: API, Clients, Using your API Key.