HHeros Developers

Version 1.0.0

Heros DOCUMENTS

The public half of every key that signs a payslip.

Base URLhttps://sandbox.droomwork.io
AuthenticationNone. Every endpoint here answers without a credential.

A payslip carries a signature and the identifier of the key that made it. This is where you get that key, so you can check the signature yourself.

What you should know before you start

You need no credential here, and there is nothing to hold. This is the only path on the platform that asks for none. Whoever is checking a payslip may never have heard of us, so an account would put the answer out of reach of the only people who want it.

Only the public half is here. There is no endpoint that returns a private key and no scope that would reach one; the two halves are kept apart, and what this answers is the half you need to verify with.

A key names the employer it belongs to. Each organisation signs with its own, so what a signature tells you is that this employer issued this payslip, not that we did.

Keys are replaced over time, and an old payslip stays checkable. A payslip names the key that signed it, so you fetch that key and not the one in use today. A key that has been replaced carries the date it was, and still verifies everything signed while it was live.

The signature is over the record, not over the page. So an altered page still carries a signature that verifies, and checking one tells you nothing about the page in your hand. GET /v1/payroll/payslips/{payslip_id}/document says what to compare.

Every operation below has two samples: Direct HTTP, with nothing but your language's own client, and Client library, with ours. Same request, same answer; the switch above each sample picks one and remembers it. Which should I use?

GET/v1/signing_keys/{signing_key_id}#

Get the key a payslip was signed with

documents.signing_keys.retrieve

This gives you the public half of a signing key, so you can check a payslip's signature for yourself without holding anything of ours.

Send the signing_key_id from the payslip in the path. You get the key as PEM, the algorithm it uses, the employer it belongs to, and the dates it was created and replaced.

No credential is needed and none is read. Whoever is checking a payslip may have no account, which is the whole reason this answers to anybody.

A key we never issued answers not_found. There is nothing here that returns a private half, under this identifier or any other.

Path parameters

signing_key_id string required

The key's identifier, starting with sgk_, such as sgk_01M1E34QM07M2N5P8R3T6V9W1Y. Take it from signing_key_id on the payslip you are checking, at GET /v1/payroll/payslips/{payslip_id}. No endpoint creates or lists keys: one is written when a payslip is signed and reaches you on that payslip.

Returns

The public half of that key, with the employer it belongs to and its dates.

object always "signing_key" required

Always signing_key. Tells you which kind of record you are looking at, so one handler can read any response.

id string required

The key's own identifier, the same one you sent in the path and the one the payslip named in signing_key_id.

organisation_id string required

The employer this key belongs to, such as org_01J8XQ4M7K2N9P3R5T7V9W1Y3Z. Each one signs with its own key, so a signature says that this employer issued the payslip. No endpoint creates or lists keys; this is the organisation the payslip you are checking belongs to.

algorithm string required

How to verify, for example ed25519. Feed public_key and this to any library that implements it; there is nothing of ours to install.

public_key string required

The public half, as PEM, beginning -----BEGIN PUBLIC KEY-----. This is what you verify a signature against.

created_at string · date-time required

When this key was created, as an RFC 3339 timestamp in UTC.

retired_at string · date-time · nullable optional

When this key was replaced, as an RFC 3339 timestamp in UTC, or null while it is the one in use. A replaced key still verifies everything signed while it was live.

Other responses

404No record with that identifier.

Errors it can return

Sends against https://sandbox.droomwork.io
Request
which?
curl -X GET "https://sandbox.droomwork.io/v1/signing_keys/sgk_01M1E34QM07M2N5P8R3T6V9W1Y"
import { Configuration, DOCUMENTSApi } from '@heros/sdk';

const api = new DOCUMENTSApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));

const result = await api.documentsSigningKeysRetrieve({ signingKeyId: 'sgk_01M1E34QM07M2N5P8R3T6V9W1Y' });
const response = await fetch('https://sandbox.droomwork.io/v1/signing_keys/sgk_01M1E34QM07M2N5P8R3T6V9W1Y', {
  method: 'GET',
  headers: {
  },
});
const result = await response.json();
import os

import heros_sdk

config = heros_sdk.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = heros_sdk.ApiClient(config)
api = heros_sdk.DOCUMENTSApi(client)

result = api.documents_signing_keys_retrieve(signing_key_id='sgk_01M1E34QM07M2N5P8R3T6V9W1Y')
import os

import requests

response = requests.request(
    'GET',
    'https://sandbox.droomwork.io/v1/signing_keys/sgk_01M1E34QM07M2N5P8R3T6V9W1Y',
    headers={
    },
)
result = response.json()
<?php
require_once __DIR__ . '/vendor/autoload.php';

$config = HerosSdk\Configuration::getDefaultConfiguration()
  ->setHost('https://sandbox.droomwork.io')
  ->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new HerosSdk\Api\DOCUMENTSApi(new GuzzleHttp\Client(), $config);

$result = $api->documentsSigningKeysRetrieve(signing_key_id: 'sgk_01M1E34QM07M2N5P8R3T6V9W1Y');
<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/signing_keys/sgk_01M1E34QM07M2N5P8R3T6V9W1Y');
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_HTTPHEADER => [
  ],
]);
$result = json_decode(curl_exec($ch), true);
import com.useheros.sdk.ApiClient;
import com.useheros.sdk.Configuration;
import com.useheros.sdk.api.DocumentsApi;

ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
DocumentsApi api = new DocumentsApi(client);

var result = api.documentsSigningKeysRetrieve("sgk_01M1E34QM07M2N5P8R3T6V9W1Y");
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/signing_keys/sgk_01M1E34QM07M2N5P8R3T6V9W1Y"))
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();
using Heros.Sdk.Api;
using Heros.Sdk.Client;

var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new DOCUMENTSApi(config);

var result = api.DocumentsSigningKeysRetrieve(signingKeyId: "sgk_01M1E34QM07M2N5P8R3T6V9W1Y");
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/signing_keys/sgk_01M1E34QM07M2N5P8R3T6V9W1Y");
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();
import heros "github.com/fenibofubara/heros-sdk-go"

ctx := context.WithValue(context.Background(), heros.ContextAPIKeys, map[string]heros.APIKey{
	"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := heros.NewConfiguration()
cfg.Servers = heros.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := heros.NewAPIClient(cfg)

result, _, err := client.DOCUMENTSAPI.DocumentsSigningKeysRetrieve(ctx, "sgk_01M1E34QM07M2N5P8R3T6V9W1Y").Execute()
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/signing_keys/sgk_01M1E34QM07M2N5P8R3T6V9W1Y", nil)
res, err := http.DefaultClient.Do(req)
if err != nil {
	return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
Response
{
  "object": "signing_key",
  "id": "sgk_01M1E34QM07M2N5P8R3T6V9W1Y",
  "organisation_id": "org_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
  "algorithm": "ed25519",
  "public_key": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEARWRKyJMc3qxJ8FhFZFK1OBs1kOJ6TFW7N0OT3hRqH1M=\n-----END PUBLIC KEY-----\n",
  "created_at": "2026-09-01T09:00:00Z",
  "retired_at": null
}