For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
Truework.comAPI StatusGet your API key
HomeGuidesAPI referenceHelp
HomeGuidesAPI referenceHelp
    • Introduction
  • Using the API
    • Authentication
    • Versioning
    • Webhooks
    • Sandbox environment
    • Monitoring
    • Limits
    • HTTP Response Signatures
  • Verification orders & reports
    • POSTCreate a target employer order
    • POSTCreate an employer search order
    • POSTCreate a Truework Direct order
    • GETGet one order
    • GETGet all orders
    • PUTCancel an order
    • GETGet one report
    • GETGet order events
    • POSTReverify a report
  • Public beta APIs
  • Previous API versions
    • API version 2022-08-01
    • API version 2020-12-07
    • API version 2019-10-15
LogoLogo
Truework.comAPI StatusGet your API key
On this page
  • Public keys
  • Signature
  • Verifying the signature
  • Code example
Using the API

HTTP Response Signatures

Was this page helpful?
Previous

Create a target employer order

Next
Built with

Truework API responses include a signature header that can be used to verify the authenticity of the API response.

Public keys

Truework’s public key used to validate the signature will be published on this page.

KEY IDNOT VALID BEFORENOT VALID AFTERBase 64 Encoded Value
tw-2021-11-112021-11-11N/AAd14e4K+/6At51wUH2B3M4ONNlRmLiSpI4NUAl+IcyA=
tw-sandbox-2021-11-112021-11-11N/AyJBzPH0p+gdRuj4qnjU1+ob0AH52gHRDXxnDW1xGaYk=

Signature

The signature is included as a header named X-Truework-Signature and includes the information required to verify the signature. The signature has three parts: keyId, headers and signature. For example:

X-Truework-Signature: keyId="tw-2021-11-11", headers="date content-length", signature="some_long_signature_b64_encoded"
Signature PartDetails
keyIdRefers to the key id of the public key that can be used to verify the signature
headersRefers to which response headers were used in the construction of the signature. Each header key is lower cased, separated by a space character
signatureRefers to the actual signature that will be verified. Truework uses Ed25519 to generate the signature

Verifying the signature

Based on the headers part of the Signature header, we can construct the message that we will use to verify the signature. The message contains the following components, separated by \n characters:

  1. Header key and value, in the format headerKey: headerValue
  2. Response body

For example, the message constructed for the API response:

Date:
Content-Length: 50
{"responseKey": "responseValue"}

Message constructed:

date: Fri, 12 Nov 2021 19:28:59 GMT\n
content-length: 50\n
{"responseKey": "responseValue"}

Using the constructed message, public key and signature, we can verify the response payload.

Code example

To verify the signature, we first parse the signature header to extract its parts:

1signature = response.get_header("X-Truework-Signature")
2
3signature_parts = {
4 i.split("=", 1)[0].strip(): i.split("=", 1)[1].strip('"')
5 for i in signature.split(",")
6}
7key_id = signature_parts["keyId"]
8part_headers = signature_parts["headers"]
9part_signature = signature_parts["signature"]

We then construct the message that we will use to verify the signature:

1def get_headers_for_message(headers_part: str, response) -> dict:
2 headers = headers_part.split(" ")
3 return {i.lower(): response.get_header(i) for i in headers}
4
5def get_message(headers: dict, body: str):
6 headers_to_sign = "\n".join([f"{key}: {value}" for key, value in headers.items()])
7 message = headers_to_sign + "\n" + body if headers_to_sign else body
8 return message
9
10headers_for_message = get_headers_for_message(part_headers, response)
11message = get_message(headers_for_message, response.body)

Finally, we verify the message using the constructed message, Truework’s public key, and signature part:

1from nacl.encoding import Base64Encoder
2from nacl.exceptions import BadSignatureError
3from nacl.signing import VerifyKey
4
5def verify_signature(message: str, verify_key_bytes: bytes, signature: str):
6 verify_key = VerifyKey(verify_key_bytes)
7 signature_b64_bytes = signature.encode()
8 signature_bytes = Base64Encoder.decode(signature_b64_bytes)
9 return verify_key.verify(message.encode(), signature_bytes)
10
11verify_key_b64_bytes = "tw_public_key_b64_encoded".encode()
12verify_key_bytes = Base64Encoder.decode(verify_key_b64_bytes)
13verify_signature(message, verify_key_bytes=verify_key_bytes, signature=part_signature)