{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/developer/auth-and-security/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition","example-box"]},"type":"markdown"},"seo":{"title":"JSON Web Signature (JWS)","siteUrl":"https://docs.wise.com","projectTitle":"Wise Platform","description":"JSON Web Signature (JWS): Implementing API Request Integrity and Non-Repudiation","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"json-web-signature-jws","__idx":0},"children":["JSON Web Signature (JWS)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"span","attributes":{"style":{"fontSize":"1.5em"}},"children":["Learn how JOSE JWS works with Wise Platform."]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["JSON Web Signature (JWS) is a JOSE specification that defines a compact and URL-safe way to represent digitally signed content. Implementing JWS in your system ensures the sender's identity and message haven't been altered, providing non-repudiation for your interactions with the Wise API."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here's a summary of how the signing process works:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Create a key pair and deliver the public key to Wise (contact your implementation manager for details on how to do this)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Wise installs the public key to be consumed by the Wise API."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Once installed, you can call JWS enabled endpoint with signed request bodies."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Wise verifies the signature using the public key provided and performs additional checks, including the validity of the URL."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Wise returns the response encoded and signed."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Your system verifies and decodes the header and payload from the returned JWS."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"id":"supply-public-key","level":2,"__idx":1},"children":["Providing public keys "]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Contact your implementation manager about submitting your public key details to Wise."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"encryption-key-requirements","__idx":2},"children":["Encryption key requirements"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When delivering the public key, Wise requires the following information:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Key Material"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Algorithm used"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"optional-key-details","__idx":3},"children":["Optional key details"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following details are optional:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["KeyID: UUID"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Expiration Timestamp"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Deletion Timestamp"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Activation Timestamp"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The KeyID, denoted in the JWS header as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kid"]},", indicates which key to use to validate the signature. This should be supplied if you plan to have multiple keys active at once, either for multiple services or rotation."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the expiration, deletion, and activation timestamps are not included, once installed, the key will remain active until Wise is instructed to remove it."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"id":"flow","level":2,"__idx":4},"children":["Using JWS endpoints workflow "]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here is a step-by-step workflow, with example commands, to manually sign a request."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wise uses a standard implementation of JOSE JWS. For more information on constructing, signing, and validating JWS, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://openid.net/specs/draft-jones-json-web-signature-04.html"},"children":["JSON Web Signature (JWS)"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"1-create-request-header--body","__idx":5},"children":["1. Create request header & body"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create a request body (according to the usual API reference) and sign it with the request URL in the header block (see example)."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Important!"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["url"]}," must be included since Wise uses this to verify the request path has not been tampered with. Both the headers and payload are signed and verified against the actual call."]}]},{"$$mdtype":"Tag","name":"ExampleBox","attributes":{"title":"Header to be signed","type":"code"},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"alg\": \"ES512\",\n  \"typ\": \"JWT\",\n  \"kid\": \"663a0e44-aa4a-4ff0-a9f8-cd99f5fbad71\",\n  \"url\": \"/v3/profiles/12345/transfers/12345/payments\"\n}\n","lang":"json"},"children":[]}]},{"$$mdtype":"Tag","name":"ExampleBox","attributes":{"title":"Payload to be signed","type":"code"},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"type\": \"BALANCE\"\n}\n","lang":"json"},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"2-sign-with-private-key","__idx":6},"children":["2. Sign with private key"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The header and body should then be base64url encoded and signed, with the signature appended as per the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://jose.readthedocs.io/en/latest/#jws"},"children":["JOSE standard for JWS"]},". It is recommended that you use an ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://jwt.io/libraries"},"children":["established library"]}," to complete this process to avoid difficulties and errors in the encoding and signing process."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This example uses the header and body as shown above and signs it with a private key. The three parts of this JWS are:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Base64(base64url) Encoded Header"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Base64(base64url) Encoded Body"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Signed header + Body"]}]},{"$$mdtype":"Tag","name":"ExampleBox","attributes":{"title":"Signed example","type":"code"},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"ewogICJhbGciOiAiRVM1MTIiLAogICJ0eXAiOiAiSldUIiwKICAia2lkIjogIjY2M2EwZTQ0LWFhNGEtNGZmMC1hOWY4LWNkOTlmNWZiYWQ3MSIsCiAgInVybCI6ICIvdjMvcHJvZmlsZXMvMTIzNDUvdHJhbnNmZXJzLzEyMzQ1L3BheW1lbnRzIgp9\n.ewogICJ0eXBlIjogIkJBTEFOQ0UiCn0=\n.Z-B7ScaZ37U_0CKrv03LTi0O0GWR2Hm5shzoEj8xRmM\n","lang":"shell"},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"3-submit-authenticated-api-request","__idx":7},"children":["3. Submit authenticated API request"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The request must include the following headers:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Content-Type: application/jose+json"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Accept: application/jose+json"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-TW-JOSE-Method: jws"]}]}]},{"$$mdtype":"Tag","name":"ExampleBox","attributes":{"title":"Complete API request example","type":"code"},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -X POST 'https://api.transferwise.com/v3/profiles/12345/transfers/12345/payments' \\\n     -H 'Authorization: Bearer XXXXXXX' \\\n     -H 'Content-Type: application/jose+json' \\\n     -H 'Accept: application/jose+json' \\\n     -H 'X-TW-JOSE-Method: jws' \\\n     -H 'Accept-Encoding: identity' \\\n     -d 'ewogICJhbGciOiAiRVM1MTIiLAogICJ0eXAiOiAiSldUIiwKICAia2lkIjogIjY2M2EwZTQ0LWFhNGEtNGZmMC1hOWY4LWNkOTlmNWZiYWQ3MSIsCiAgInVybCI6ICIvdjMvcHJvZmlsZXMvMTIzNDUvdHJhbnNmZXJzLzEyMzQ1L3BheW1lbnRzIgp9.ewogICJ0eXBlIjogIkJBTEFOQ0UiCn0=.Z-B7ScaZ37U_0CKrv03LTi0O0GWR2Hm5shzoEj8xRmM'\n","lang":"bash"},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"4-verify-the-response","__idx":8},"children":["4. Verify the response"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Verify the response by fetching the latest Wise public key and checking the signature. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api-reference/jose/joseresponsepublickeysget"},"children":["Get Wise JWT public key"]}," for details."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The response is a fully formed JWS with a Base64 encoded JSON body."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wise will sign the response using the same algorithm that was used to sign the request body."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If there is no body in the original request, the ES512 algorithm will be used for signing the response."]},{"$$mdtype":"Tag","name":"ExampleBox","attributes":{"title":"Request","type":"code"},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"  $ curl -i -X GET 'https://api.wise-sandbox.com/v1/auth/jwt-public-key?algorithm=ES512&scope=PAYLOAD_SIGNING' \\\n         -H 'Content-Type: application/json' \\\n         -H 'Authorization: Bearer <your api token>'\n","lang":"bash"},"children":[]}]}]},"headings":[{"value":"JSON Web Signature (JWS)","id":"json-web-signature-jws","depth":1},{"value":"Providing public keys","id":"supply-public-key","depth":2},{"value":"Encryption key requirements","id":"encryption-key-requirements","depth":3},{"value":"Optional key details","id":"optional-key-details","depth":3},{"value":"Using JWS endpoints workflow","id":"flow","depth":2},{"value":"1. Create request header & body","id":"1-create-request-header--body","depth":3},{"value":"2. Sign with private key","id":"2-sign-with-private-key","depth":3},{"value":"3. Submit authenticated API request","id":"3-submit-authenticated-api-request","depth":3},{"value":"4. Verify the response","id":"4-verify-the-response","depth":3}],"frontmatter":{"seo":{"description":"JSON Web Signature (JWS): Implementing API Request Integrity and Non-Repudiation","title":"JSON Web Signature (JWS)"}},"lastModified":"2026-04-30T08:54:00.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/developer/auth-and-security/jose/jose-jws","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}