v4 Specification

Describes the v4 (SecOps) Protegrity Data Protection API specification

The Protegrity Data Protection API v4 is the recommended interface for all new integrations. AWS Lambda service limits the maximum size of a payload to 6 MB. Client applications must ensure their payload size is within this limit.

Overview

The Protegrity Data Protection API v4 (SecOps v4) lets callers protect, unprotect, and reprotect (unprotect with one data element, then protect with another) sensitive data values according to a configured data security policy.

This is the new, canonical JSON API and is the recommended interface for all new integrations. It replaces the older v1 and Legacy REST formats, which are now deprecated.

  • Base path: /pty/api/secops/v4
  • Content type: application/json for both request and response
  • Method: all operations are HTTP POST

Endpoints

MethodPathPurpose
POST/pty/api/secops/v4/protectProtect data values using a data element.
POST/pty/api/secops/v4/unprotectUnprotect previously protected values.
POST/pty/api/secops/v4/reprotectUnprotect with one data element and protect with another.

Authentication

Authentication uses a JWT bearer token supplied in the Authorization header (the scheme keyword is matched case-insensitively):

Authorization: Bearer <token>

Enforcement is configured at deployment time and controlled by two configuration properties: authorization (set to jwt to enable JWT mode) and jwt_verify (set to 1 to verify the token signature).

When authorization is set to jwt:

  • A missing, empty, or malformed Authorization header returns HTTP 403, regardless of the jwt_verify setting.
  • Signature and expiry verification runs only when jwt_verify is 1. A failed verification (bad signature, expired token, and so on) returns HTTP 403. When jwt_verify is not 1, the token is decoded for its claims but the signature is not checked.
  • The user identity is taken from a JWT claim (configurable with jwt_user_claim, default cognito:username). See the user field note under Request for how the body user field interacts with this.

Request

protect / unprotect

{
  "user": "alice",
  "payload": [
    {
      "dataElement": "DE_SSN",
      "data": ["675-00-7848", "105-74-8112"],
      "encoding": "utf8",
      "externalIv": "s40de6wf6",
      "externaltweak": "e8wf6s30d",
      "id": "1"
    }
  ]
}

reprotect

The reprotect operation adds the new* fields that describe the target data element.

{
  "user": "alice",
  "payload": [
    {
      "dataElement": "DE_SSN",
      "newDataElement": "DE_SSN_2",
      "data": ["340-75-9971"],
      "externalIv": "s40de6wf6",
      "newExternalIv": "02983hd7sz",
      "externaltweak": "e8wf6s30d",
      "newExternaltweak": "h4egm1hjd"
    }
  ]
}

Field reference

FieldLocationTypeRequiredNotes
usertop-levelstringOptional (conditional at runtime — see note below)Identity performing the operation.
payloadtop-levelarray (min 1 item)RequiredOne or more work items; each is processed independently.
dataElementpayload itemstringRequiredPolicy data element. In reprotect this is the source data element.
newDataElementpayload itemstringRequired for reprotectTarget data element that the values are protected with during reprotect.
datapayload itemarray of string/number (min 1)RequiredValues to process. null entries are allowed.
encodingpayload itemenumOptional, default utf8One of: utf8, hex, base64, base64_mime, base64_pem, base64_url.
externalIvpayload itemstringOptionalExternal initialization vector. In reprotect, the IV for the source data element.
newExternalIvpayload itemstringOptional (reprotect)IV for the target data element.
externaltweakpayload itemstringOptionalExternal tweak used with FPE. Source-data-element tweak in reprotect. Note the lowercase t.
newExternaltweakpayload itemstringOptional (reprotect)Tweak for the target data element. Note the lowercase t.
idpayload itemstring or numberOptionalClient correlation tag, echoed back in the matching result with its JSON type preserved (a number stays a number, a string stays a string). A string id longer than 128 characters is rejected with an HTTP 400 validation error (maxLength: 128), enforced consistently across protect, unprotect, and reprotect. The number form is unconstrained.

Response

Success (HTTP 200)

Both full success and partial success return HTTP 200. The response envelope is { errorCount, results }, where the order of results matches the order of the input payload.

{
  "errorCount": 0,
  "results": [
    { "encoding": "utf8", "data": ["340-75-9971", "064-18-7624"], "returnCode": 8 }
  ]
}

Each result is one of two shapes:

  • Success result (resultSuccess): returnCode (the engine’s success code — 6 for protect, 8 for unprotect, 50 for reprotect, or 11 when an inactive key was used), encoding, data[], and optional id.
  • Failure result (resultFailure): returnCode (a non-success engine code), message, and optional id.

A partial-success response (one item failed, one succeeded) still returns HTTP 200:

{
  "errorCount": 1,
  "results": [
    { "id": "1", "message": "Input too short", "returnCode": 22 },
    { "id": "2", "encoding": "base64", "data": ["..."], "returnCode": 8 }
  ]
}

Error responses

HTTPWhenBody shape
200Full or partial success. Per-item failures appear in results and are counted by errorCount.{ errorCount, results[] }
400A request-level validation error — for example, a missing or empty payload; a missing dataElement (or newDataElement for reprotect) or data; a missing or unresolvable user; an empty data array; an id string longer than 128 characters; or an invalid data item. The request was not processed.{ "message": "..." }
403An Authorization header or token problem: missing, empty, malformed, or (when jwt_verify=1) a failed signature or expiry verification.{ "message": "..." }
500A server-side fault — a configuration error (for example, signature verification is enabled but no signing secret is configured), the policy being missing or unavailable, or any other unexpected error.{ "message": "..." }

Return codes

returnCode is the protection engine’s return code. A success result carries a success code; a failure result carries a failure code together with a descriptive message.

Success codes (on a success result):

returnCodeMeaning
6Protect succeeded.
8Unprotect succeeded.
11Unprotect succeeded using an inactive key.
50Reprotect succeeded.
10Access OK; no data transformed.
27Application authorized.

Failure codes (on a failure result):

returnCodeMeaning
1User not found in the policy.
2Data element not found in the policy.
3User lacks permission for the requested operation.
4Tweak is null.
5Integrity check failed.
7Protect operation failed.
9Unprotect operation failed.
12Input is null or not within allowed limits.
13Internal error (also used when an unexpected internal fault has no other engine code).
14Failed to load the data encryption key.
15Tweak input is too long.
19Unsupported tweak for the data element.
20Out of memory.
21Input or output buffer too small.
22Data is too short to protect or unprotect.
23Data is too long to protect or unprotect.
26Unsupported algorithm or action for the data element.
28Application not authorized.
31Policy not available.
44Input data content is not valid.
49Unsupported input encoding for the data element.

Examples

protect

Simple protect call with the minimum required input:

{
  "user": "alice",
  "payload": [
    { "data": ["George Washington"], "dataElement": "DE_NAME" }
  ]
}

Response:

{
  "errorCount": 0,
  "results": [
    { "encoding": "utf8", "data": ["EdVz2X i5a2FXNW5jR"], "returnCode": 6 }
  ]
}

Protect using FPE with an external tweak:

{
  "user": "alice",
  "payload": [
    {
      "data": ["675-00-7848", "105-74-8112"],
      "dataElement": "DE_FPE",
      "externaltweak": "e8wf6s30d"
    }
  ]
}

unprotect

Simple unprotect call with the minimum required input:

{
  "user": "alice",
  "payload": [
    { "data": ["EdVz2X i5a2FXNW5jR"], "dataElement": "DE_NAME" }
  ]
}

Response:

{
  "errorCount": 0,
  "results": [
    { "encoding": "utf8", "data": ["George Washington"], "returnCode": 8 }
  ]
}

reprotect

Simple reprotect call (from one data element to another):

{
  "user": "alice",
  "payload": [
    {
      "data": ["EdVz2X i5a2FXNW5jR"],
      "dataElement": "DE_NAME",
      "newDataElement": "DE_NAME_2"
    }
  ]
}

Response:

{
  "errorCount": 0,
  "results": [
    { "encoding": "utf8", "data": ["m9yGNp v2ZiB2YWx1"], "returnCode": 50 }
  ]
}

Error examples

A 400 response for a request-level validation error (for example, a missing payload):

{ "message": "'payload' parameter is missing" }

A 403 response when the authorization token is missing or expired:

{ "message": "Authorization header was not found" }

A 500 response for a configuration error:

{ "message": "JWT secret is missing" }

Headers

HeaderDirectionNotes
AuthorizationrequestBearer <jwt> (when JWT authorization is enabled).
X-Correlation-IDrequest → response (conditional)Optional request-tracking ID. When the request supplies it, it is echoed back on every response — on full-success, partial-success, and all-failure 200 responses, and on 400, 403, and 500 responses. When the request omits it, no header is returned.

Migrating from v1 / Legacy

Aspectv1 / LegacySecOps v4
PathAny path except secopsOnly /pty/api/secops/v4/*
Operation selectionLast segment of the URL path (…/protect, and so on)Last segment of the URL path (/protect, /unprotect, /reprotect) — same mechanism
Format selectionBody must contain the arguments arrayRequest path must start with /pty/api/secops/v4
Request wrapperargumentspayload
Data element fielddata_element / old_data_elementdataElement / newDataElement
External IV fieldexternal_iv / old_external_ivexternalIv / newExternalIv
FPE tweakNot presentexternaltweak / newExternaltweak
Success envelope{ success, results }{ errorCount, results }
400 error bodySuccess-shaped envelope{ message } object

Last modified : June 26, 2026