Skip to main content

Squillify development is paused indefinitely. Read why, and discover what this experiment achieved. Read the story

MicroSkills Reference

Consent Record Validator

governance.consent_record_validate

ProductionBounded custom (Class B)Deterministicstrictinstantv1.0.0
No network

Overview

You send one consent record and the policy it should satisfy, plus the instant to evaluate it at, and we report what the record says: which of the six completeness elements are present, whether the lawful basis is one your policy permits, whether the consent had expired or been withdrawn at that instant, and the window it covered. Findings are closed codes with a field path and nothing else — the subject reference never appears anywhere in the response, not in a message, not in a count key. We validate the record you sent against the policy you sent; we certify no regulation and grant no permission to process anything.

A consent store is only as good as the records in it, and the ways a record goes wrong are boring and repetitive: no lawful basis, no withdrawal state, an expiry that disagrees with the duration next to it, a withdrawal dated before the grant. Checking that by hand across a store does not scale, and writing the checklist a fourth time in a fourth service is how two services disagree about the same record.

Reliability

Fully deterministic and independent of the machine: the same record, policy and asOf give the same verdict whatever the default locale, zone or charset. Two design choices are worth knowing before you rely on the output. First, a record stating both expiresAt and grantedAt plus duration that disagree by even one second is refused rather than resolved, because picking a winner would let a broken record validate cleanly under whichever precedence you did not expect. Second, consent is valid over the half-open window from grantedAt up to but not including the effective expiry, so an asOf exactly equal to the expiry is expired, and the same rule makes an asOf equal to withdrawnAt withdrawn. Severity is fixed per code rather than varied by policy, and the require flags decide whether an issue is raised at all, not how badly. Refusals, and what to do about each. GOV_CONSENT_INPUT_TOO_LARGE means the declared request is past the 65,536-byte inline limit, so send fewer purposes. GOV_CONSENT_RECORD_INVALID means a record member is the wrong type, empty where a value is needed, or outside its charset, and the message names the path. GOV_CONSENT_FIELD_UNKNOWN means a property we do not declare turned up, so delete it rather than assuming it was read. GOV_CONSENT_POLICY_INVALID means the policy block is malformed — a non-string purpose id or an out-of-range maxDurationDays. GOV_CONSENT_PURPOSE_LIMIT_EXCEEDED means more than 64 purposes arrived in the record or the policy. GOV_CONSENT_PURPOSE_ID_DUPLICATE means one purpose id appears twice, which makes its granted flag ambiguous, so merge them. GOV_CONSENT_LAWFUL_BASIS_UNSUPPORTED means a basis outside the six Article 6(1) members arrived in the record or in allowedLawfulBases. GOV_CONSENT_WITHDRAWAL_STATE_UNSUPPORTED means withdrawalState is not ACTIVE, WITHDRAWN or SUPERSEDED. GOV_CONSENT_EVIDENCE_METHOD_UNSUPPORTED means evidence.method is outside the five members; send UNKNOWN rather than inventing a label. GOV_CONSENT_WITHDRAWN_AT_MISSING means the state says WITHDRAWN with no instant, which cannot be placed on the timeline, so supply withdrawnAt. GOV_CONSENT_TIMESTAMP_INVALID means a record instant carries no explicit offset or does not parse, so add the offset. GOV_CONSENT_DURATION_INVALID means the duration is not an ISO-8601 duration between P1D and the P36500D equivalent. GOV_CONSENT_EXPIRY_CONFLICT means expiresAt and grantedAt plus duration state two different instants, so correct the record rather than asking us to choose. GOV_CONSENT_ASOF_INVALID means asOf carries no explicit offset or does not parse. GOV_CONSENT_TIMEZONE_REQUIRED means the duration carries a calendar component, where a day is 23, 24 or 25 hours, so send policy.timeZone. GOV_CONSENT_TIMEZONE_UNKNOWN means the zone is not an IANA id such as Europe/Amsterdam. GOV_CONSENT_WORK_REFUSED means the projected checks went past the budget of 1,024, and the refusal reports both numbers.

Context footprint

A verdict, a state, a bounded issue list of codes and paths, and small counts. No record value comes back. A successful call costs 1 execution credit.

When to use it

When you have a consent record and a written policy, and you want the record's completeness and its state at a particular instant, with the field paths to fix.

When you need a runtime permission decision, a compliance certificate, or an evaluation against a clock we do not have.

Scope

Note
One consent record checked against one caller-supplied policy at one caller-supplied instant, reported as closed codes and field paths.

Non-goals

  • Does not certify compliance with GDPR or any other regulation — it checks the record against the policy you sent
  • Does not decide whether processing may proceed; nothing here is an authorization decision the platform acts on
  • Does not store, index or forward the record
  • Does not read a clock — expiry and withdrawal are evaluated at your asOf
  • Does not echo the subject reference, a purpose id or a timestamp you sent

Properties

IdempotentRetry safeStreaming supportedFile input supportedRequires external service

Capabilities

validation

Cost & billing

Flat rate per invocation

MetercallsBillable onsuccessCost per call1 credit

File handling

Accepts file_refProduces file_refMax input64 KB

How we handle your data

Sensitive input, safe output
What this means

This skill may receive sensitive content, but it does not target sensitive data and returns only a structured non-sensitive result.

Squillify guarantees
  • Runs inside Squillify
  • This skill runs inside Squillify.
  • Payloads are not sent to an external service by this skill.
  • Squillify does not permanently store submitted payloads.
  • Telemetry records metadata only, not submitted content.
  • Submitted payloads are not used for training.
  • Submitted payloads are not reviewed by humans.
  • This skill does not target sensitive data.
  • The response does not contain submitted content.
Your responsibility

Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.

Read the Microskill Data Handling Policy

Input schema

FieldTypeRequiredDescription
recordobjectYesClosed consent record whose members are all optional so incompleteness is reported rather than refused.
policyobjectNoOptional completeness policy for required purposes, permitted bases, max duration, and which fields must be present; omit it for the published completeness defaults.
asOfstringYesInstant expiry and withdrawal are evaluated at, as ISO-8601 with an explicit offset.

Output schema

FieldTypeRequiredDescription
validbooleanYesTrue when no ERROR-severity issue is present; a warning does not fail the record.
statestringYesOverall record state after expiry and withdrawal ranking.
issuesarrayYesUp to 200 findings of code, severity, and fieldPath; empty on a complete in-date record.
effectiveFromstringNoGrant instant in UTC; omitted when the record declares none.
effectiveUntilstringNoEarlier of withdrawal and expiry in UTC; omitted when neither is declared.
summaryobjectYesClosed counters for purposes, lawful basis, asOf, optional time zone, issue counts, checks applied, and truncation.

API contract

POST /v1/execute
curl
curl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"governance.consent_record_validate","input":{"record":{"subjectRef":"subj_9d41","purposes":[{"id":"marketing_email","granted":true}],"lawfulBasis":"CONSENT","grantedAt":"2025-03-01T08:00:00Z","expiresAt":"2027-03-01T08:00:00Z","withdrawalState":"ACTIVE"},"asOf":"2026-07-29T12:00:00Z"}}'
Integrations
TypeScript SDK
import { Squillify } from "@squillify/sdk";

const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });

const { output } = await sq.execute("governance.consent_record_validate", {"asOf":"2026-07-29T12:00:00Z","policy":{"allowedLawfulBases":["CONSENT"],"requiredPurposes":["marketing_email","product_analytics"],"maxDurationDays":730,"requireExplicitExpiry":true,"requireWithdrawalMechanism":true,"requireNoticeVersion":true},"record":{"subjectRef":"subj_9d41","purposes":[{"id":"marketing_email","granted":true},{"id":"product_analytics","granted":true}],"lawfulBasis":"CONSENT","grantedAt":"2025-03-01T08:00:00Z","expiresAt":"2027-03-01T08:00:00Z","withdrawalState":"ACTIVE","noticeVersion":"notice-2025.03","evidence":{"method":"EXPLICIT_OPT_IN"},"withdrawalMechanism":"SELF_SERVICE"}});

Errors

CodeHTTPRetryableDescription
VALIDATION_ERROR400NoThe request payload failed schema validation.
UNAUTHORIZED401NoMissing or invalid API key.
SKILL_NOT_ACCESSIBLE403NoThe API key is not granted access to this skill.
SKILL_NOT_AVAILABLE_FOR_PLAN403NoThis skill is not included in your current plan.
PLAN_ELIGIBILITY_UNAVAILABLE503YesPlan eligibility could not be decided. Retry after backoff.
SKILL_NOT_FOUND404NoThe requested skill or version does not exist.
TENANT_RATE_LIMITED429YesRequest rate limit exceeded. Retry after backoff.
QUOTA_EXCEEDED429YesPlan quota exhausted. Retryable once the quota period resets.
EXECUTION_TIMEOUT504YesExecution exceeded the allowed time budget.
GOV_CONSENT_INPUT_TOO_LARGE429NoA size, quota, rate, or time limit was exceeded.
GOV_CONSENT_RECORD_INVALID400NoThe request payload failed this skill's input validation.
GOV_CONSENT_FIELD_UNKNOWN400NoThe request payload failed this skill's input validation.
GOV_CONSENT_POLICY_INVALID400NoThe request payload failed this skill's input validation.
GOV_CONSENT_PURPOSE_LIMIT_EXCEEDED429NoA size, quota, rate, or time limit was exceeded.
GOV_CONSENT_PURPOSE_ID_DUPLICATE400NoThe request payload failed this skill's input validation.
GOV_CONSENT_LAWFUL_BASIS_UNSUPPORTED400NoThe skill does not support the requested variant.
GOV_CONSENT_WITHDRAWAL_STATE_UNSUPPORTED400NoThe skill does not support the requested variant.
GOV_CONSENT_EVIDENCE_METHOD_UNSUPPORTED400NoThe skill does not support the requested variant.
GOV_CONSENT_WITHDRAWN_AT_MISSING400NoThe request payload failed this skill's input validation.
GOV_CONSENT_TIMESTAMP_INVALID400NoThe request payload failed this skill's input validation.
GOV_CONSENT_DURATION_INVALID400NoThe request payload failed this skill's input validation.
GOV_CONSENT_EXPIRY_CONFLICT400NoThe request payload failed this skill's input validation.
GOV_CONSENT_ASOF_INVALID400NoThe request payload failed this skill's input validation.
GOV_CONSENT_TIMEZONE_REQUIRED400NoThe request payload failed this skill's input validation.
GOV_CONSENT_TIMEZONE_UNKNOWN400NoThe request payload failed this skill's input validation.
GOV_CONSENT_WORK_REFUSED429NoA size, quota, rate, or time limit was exceeded.

Other limits

LimitValue
Recommended inline bytes32 KiB

Limitations

  • Does not certify compliance with GDPR or any other regulation — it checks the record against the policy you sent
  • Does not decide whether processing may proceed; nothing here is an authorization decision the platform acts on
  • Does not store, index or forward the record
  • Does not read a clock — expiry and withdrawal are evaluated at your asOf
  • Does not echo the subject reference, a purpose id or a timestamp you sent
  • Gating a processing decision at runtime
  • Proving a regulator's requirements are met
  • Validating a consent record whose expiry you want us to guess from today's date

How to call

POST /v1/execute (requires authentication)

Request bodyjson
{
  "skillKey": "governance.consent_record_validate",
  "input": {
    "asOf": "2026-07-29T12:00:00Z",
    "policy": {
      "allowedLawfulBases": [
        "CONSENT"
      ],
      "requiredPurposes": [
        "marketing_email",
        "product_analytics"
      ],
      "maxDurationDays": 730,
      "requireExplicitExpiry": true,
      "requireWithdrawalMechanism": true,
      "requireNoticeVersion": true
    },
    "record": {
      "subjectRef": "subj_9d41",
      "purposes": [
        {
          "id": "marketing_email",
          "granted": true
        },
        {
          "id": "product_analytics",
          "granted": true
        }
      ],
      "lawfulBasis": "CONSENT",
      "grantedAt": "2025-03-01T08:00:00Z",
      "expiresAt": "2027-03-01T08:00:00Z",
      "withdrawalState": "ACTIVE",
      "noticeVersion": "notice-2025.03",
      "evidence": {
        "method": "EXPLICIT_OPT_IN"
      },
      "withdrawalMechanism": "SELF_SERVICE"
    }
  }
}

Examples

A complete, in-date, active record under a two-purpose policy

Inputjson
{
  "asOf": "2026-07-29T12:00:00Z",
  "policy": {
    "allowedLawfulBases": [
      "CONSENT"
    ],
    "requiredPurposes": [
      "marketing_email",
      "product_analytics"
    ],
    "maxDurationDays": 730,
    "requireExplicitExpiry": true,
    "requireWithdrawalMechanism": true,
    "requireNoticeVersion": true
  },
  "record": {
    "subjectRef": "subj_9d41",
    "purposes": [
      {
        "id": "marketing_email",
        "granted": true
      },
      {
        "id": "product_analytics",
        "granted": true
      }
    ],
    "lawfulBasis": "CONSENT",
    "grantedAt": "2025-03-01T08:00:00Z",
    "expiresAt": "2027-03-01T08:00:00Z",
    "withdrawalState": "ACTIVE",
    "noticeVersion": "notice-2025.03",
    "evidence": {
      "method": "EXPLICIT_OPT_IN"
    },
    "withdrawalMechanism": "SELF_SERVICE"
  }
}
Expected outputjson
{
  "effectiveUntil": "2027-03-01T08:00:00Z",
  "effectiveFrom": "2025-03-01T08:00:00Z",
  "issues": [],
  "summary": {
    "purposeCount": 2,
    "grantedPurposeCount": 2,
    "lawfulBasis": "CONSENT",
    "asOf": "2026-07-29T12:00:00Z",
    "errorCount": 0,
    "warningCount": 0,
    "infoCount": 0,
    "checksApplied": 40,
    "truncated": false
  },
  "valid": true,
  "state": "VALID"
}

Withdrawn and expired at the same instant, reporting both

Inputjson
{
  "asOf": "2026-07-29T12:00:00Z",
  "record": {
    "subjectRef": "subj_9d41",
    "grantedAt": "2024-01-15T09:00:00Z",
    "expiresAt": "2026-01-15T09:00:00Z",
    "withdrawalState": "WITHDRAWN",
    "purposes": [
      {
        "id": "marketing_email",
        "granted": true
      }
    ],
    "withdrawnAt": "2025-06-01T10:30:00Z",
    "lawfulBasis": "CONSENT"
  }
}
Expected outputjson
{
  "effectiveUntil": "2025-06-01T10:30:00Z",
  "effectiveFrom": "2024-01-15T09:00:00Z",
  "issues": [
    {
      "code": "CONSENT_WITHDRAWN",
      "severity": "INFO",
      "fieldPath": "record.withdrawnAt"
    },
    {
      "code": "CONSENT_EXPIRED",
      "severity": "INFO",
      "fieldPath": "record.expiresAt"
    }
  ],
  "summary": {
    "purposeCount": 1,
    "grantedPurposeCount": 1,
    "lawfulBasis": "CONSENT",
    "asOf": "2026-07-29T12:00:00Z",
    "errorCount": 0,
    "warningCount": 0,
    "infoCount": 2,
    "checksApplied": 28,
    "truncated": false
  },
  "valid": true,
  "state": "WITHDRAWN"
}
  • Screen a consent store for records missing an element your own policy requires
  • Reconstruct the lawful-processing window of one record, and see whether withdrawal or expiry ended it

Avoid for

  • Gating a processing decision at runtime
  • Proving a regulator's requirements are met
  • Validating a consent record whose expiry you want us to guess from today's date

Composable with

Safety & privacy

  • Runs without calling any external service.
  • Your payloads are never stored permanently.
  • Telemetry captures metadata only — never your payload contents.
  • We never train models on your payloads.
  • No human reviews your payloads.

Tags

compliancevalidationgovernanceconsent