---
id: service-create-individual-consent-record-and-signature
title: "Create consent record and signature"
description: "This endpoint is used to create a consent record and signature object. This returns the same objects with the PK defined."
sidebar_label: "Create consent record and signature"
hide_title: true
hide_table_of_contents: true
api: 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
sidebar_class_name: "post api-method"
info_path: docs/consent-management-individual-api/igrant-io-api-documentation
custom_edit_url: null
---

> **Build this with an AI coding agent.** Install the iGrant.io Agent Skills, then ask your agent to build the integration:
>
> ```bash
> npx skills add L3-iGrant/skills
> ```


import ApiTabs from "@theme/ApiTabs";
import DiscriminatorTabs from "@theme/DiscriminatorTabs";
import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import SecuritySchemes from "@theme/ApiExplorer/SecuritySchemes";
import MimeTabs from "@theme/MimeTabs";
import ParamsItem from "@theme/ParamsItem";
import ResponseSamples from "@theme/ResponseSamples";
import SchemaItem from "@theme/SchemaItem";
import SchemaTabs from "@theme/SchemaTabs";
import Markdown from "@theme/Markdown";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";

<h1 className={"openapi__heading"}>Create consent record and signature</h1>

<MethodEndpoint method={"post"} path={"/service/individual/record/consent-record"}></MethodEndpoint>



This endpoint is used to create a consent record and signature object. This returns the same objects with the PK defined.

## Request

<details style={{"marginBottom":"1rem"}} className={"openapi-markdown__details"} data-collapsed={false} open={true}><summary style={{}}><h3 className={"openapi-markdown__details-summary-header-params"}>Header Parameters</h3></summary><div><ul><ParamsItem className={"paramsItem"} param={{"in":"header","name":"X-ConsentBB-IndividualId","required":true,"schema":{"type":"string"},"description":"Individual ID"}}></ParamsItem></ul></div></details><MimeTabs className={"openapi-tabs__mime"}><TabItem label={"application/json"} value={"application/json-schema"}><details style={{}} className={"openapi-markdown__details mime"} data-collapsed={false} open={true}><summary style={{}} className={"openapi-markdown__details-summary-mime"}><h3 className={"openapi-markdown__details-summary-header-body"}>Body</h3></summary><div style={{"textAlign":"left","marginLeft":"1rem"}}></div><ul style={{"marginLeft":"1rem"}}><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}} className={"openapi-markdown__details"}><summary style={{}}><span className={"openapi-schema__container"}><strong className={"openapi-schema__property"}>consentRecord</strong><span className={"openapi-schema__name"}> object</span><span className={"openapi-schema__divider"}></span><span className={"openapi-schema__required"}>required</span></span></summary><div style={{"marginLeft":"1rem"}}><div style={{"marginTop":".5rem","marginBottom":".5rem"}}>

A consent record expresses consent (as defined in this building block's specification) to a single DataAgreement. There must be a UNIQUE constraint on (data agreement revision, individual)

</div><SchemaItem collapsible={false} name={"id"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"65471222e8c7c3bb3c2c9901","description":"Objects may be passed back by some API endpoints without an ID (PK), denoting that they are a \"draft\", i.e. a ConsentRecord that is not yet stored in the database and only exist in transit. Draft ConsentRecords do not have a Revision, but if paired up with a Signature, a valid Revision should be generated."}}></SchemaItem><SchemaItem collapsible={false} name={"dataAgreementId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","x-fk-model":"DataAgreement","description":"The DataAgreement to which consent has been given"}}></SchemaItem><SchemaItem collapsible={false} name={"dataAgreementRevisionId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","x-fk-model":"Revision","description":"The Revision of the data agreement which consent has been given to"}}></SchemaItem><SchemaItem collapsible={false} name={"dataAgreementRevisionHash"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"a1b2c3d4e5f6...","description":"Copy of the revision hash. The hash is the included in the signature and ensures against tampering with the original agreement."}}></SchemaItem><SchemaItem collapsible={false} name={"individualId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","x-fk-model":"Individual","description":"The Individual who has signed this consent record"}}></SchemaItem><SchemaItem collapsible={false} name={"optIn"} required={false} schemaName={"boolean"} qualifierMessage={undefined} schema={{"type":"boolean","format":"","example":true,"description":"True: The individual has positively opted in. False: The individual has explicitly said no (or withdrawn a previous consent)."}}></SchemaItem><SchemaItem collapsible={false} name={"state"} required={true} schemaName={"string"} qualifierMessage={"**Possible values:** [`unsigned`, `signed`]"} schema={{"type":"string","format":"","example":"signed","description":"The state field is used to record state changes after-the-fact. It is maintained by the Consent BB itself. Valid states: unsigned/pending more signatures/signed","enum":["unsigned","signed"]}}></SchemaItem><SchemaItem collapsible={false} name={"signatureId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","x-fk-model":"Signature","description":"A signature that hashes all the values of the consent record and has signed it with the key of the Invidiual, making it verifiable and tamper-proof. TBD: Relation to a Signature schema?"}}></SchemaItem><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}} className={"openapi-markdown__details"}><summary style={{}}><span className={"openapi-schema__container"}><strong className={"openapi-schema__property"}>sectorPreferences</strong><span className={"openapi-schema__name"}> object[]</span></span></summary><div style={{"marginLeft":"1rem"}}><li><div style={{"fontSize":"var(--ifm-code-font-size)","opacity":"0.6","marginLeft":"-.5rem","paddingBottom":".5rem"}}>Array [</div></li><SchemaItem collapsible={false} name={"sector"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"","description":"Name of the sector"}}></SchemaItem><SchemaItem collapsible={false} name={"optIn"} required={false} schemaName={"boolean"} qualifierMessage={undefined} schema={{"type":"boolean","description":"Defines sector is opted in or not"}}></SchemaItem><SchemaItem collapsible={false} name={"isLastUpdated"} required={false} schemaName={"boolean"} qualifierMessage={undefined} schema={{"type":"boolean","description":"Defines consent record for this sector is last updated"}}></SchemaItem><li><div style={{"fontSize":"var(--ifm-code-font-size)","opacity":"0.6","marginLeft":"-.5rem"}}>]</div></li></div></details></SchemaItem></div></details></SchemaItem><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}} className={"openapi-markdown__details"}><summary style={{}}><span className={"openapi-schema__container"}><strong className={"openapi-schema__property"}>signature</strong><span className={"openapi-schema__name"}> object</span><span className={"openapi-schema__divider"}></span><span className={"openapi-schema__required"}>required</span></span></summary><div style={{"marginLeft":"1rem"}}><div style={{"marginTop":".5rem","marginBottom":".5rem"}}>

A generic signature contains a cryptographic hash of some value,  together with a signature created by some private key in another system.  Required signing methods: Revision object or another Signature object.


</div><SchemaItem collapsible={false} name={"id"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"65471222e8c7c3bb3c2c5501","description":"Objects may be passed back by some API endpoints without an id (PK), denoting that they are a \"draft\", i.e. a Signature that is not yet stored in the database and only exists in transit."}}></SchemaItem><SchemaItem collapsible={false} name={"payload"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"{...}","description":"The final payload that is signed, constructed as a JSON serialisation of fields {verificationPayload: ..., verificationPayloadHash: ..., verificationMethod: ..., verificationArtifact: ..., verificationSignedBy: ..., verificationJwsHeader, timestamp: ..., signedWithoutObjectReference: ..., objectType: ..., objectReference: ...}. Serialised as a JSON dict. If the signature is generated before anything is stored in the database (and has a PK), then the objectReference should be omitted from the payload but filled in afterwards."}}></SchemaItem><SchemaItem collapsible={false} name={"signature"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"eyJhbGciOiJFZERTQSJ9...","description":"Signature of payload hash, the format of the signature should be specified by either verificationMethod or verificationJwsHeader"}}></SchemaItem><SchemaItem collapsible={false} name={"verificationMethod"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"Ed25519Signature2020","description":"A well-known string denoting which method is used. Valid values: TBD. This might be expanded with supported verification methods. There may be a minimal set of supported methods necessary."}}></SchemaItem><SchemaItem collapsible={false} name={"verificationPayload"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"{...}","description":"Internally generated serialised version of the data referenced by objectType and objectReference - by extracting and serialising their data as JSON"}}></SchemaItem><SchemaItem collapsible={false} name={"verificationPayloadHash"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"a1b2c3d4e5f6...","description":"Internally generated cryptographic hash of the value to be signed, i.e. the value of verificationPayload"}}></SchemaItem><SchemaItem collapsible={false} name={"verificationArtifact"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"","description":"A verification artifact in the form of a scanned object, image, signature etc"}}></SchemaItem><SchemaItem collapsible={false} name={"verificationSignedBy"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"did:key:z6Mkf...","description":"Because an identifier's information may change over time, there is a need to store that information at the time of signing. In the case of a cryptographic signature, this field should contain some identifier for looking up or verifying the public key of the signing party. In the case of a non-cryptographic signature, this field could contain a natural individual's names, personal number, email addresses - store a snapshot that binds to the signature at the time of signing. In the case of a cryptographic signature, this may be the fingerprint of the individual's public key or in some cases, a token from the user's ID session."}}></SchemaItem><SchemaItem collapsible={false} name={"verificationSignedAs"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"individual","description":"DRAFT FIELD: Specifies the relationship between the authorising signature and the invidual which the payload concerns. This is relevant for Consent Records. Possible values: \"individual\" / \"delegate\"."}}></SchemaItem><SchemaItem collapsible={false} name={"verificationJwsHeader"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"","description":"Alternative to the verificationMethod, verificationHash and verificationSignature, give a JWS serialised object (RFC7515)"}}></SchemaItem><SchemaItem collapsible={false} name={"timestamp"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"2024-01-15T10:30:00Z","description":"Timestamp of signature, currently this field isn't part of the payload so it's not tamper-proof"}}></SchemaItem><SchemaItem collapsible={false} name={"signedWithoutObjectReference"} required={false} schemaName={"boolean"} qualifierMessage={undefined} schema={{"type":"boolean","format":"","example":false,"description":"Indicates that objectReference was left blank in the serialised version that was signed"}}></SchemaItem><SchemaItem collapsible={false} name={"objectType"} required={false} schemaName={"string"} qualifierMessage={"**Possible values:** [`revision`, `signature`]"} schema={{"type":"string","format":"","example":"revision","description":"Name of the schema model that objectReference points to. Values: \"signature\" or \"revision\"","enum":["revision","signature"]}}></SchemaItem><SchemaItem collapsible={false} name={"objectReference"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"65471222e8c7c3bb3c2c6601","description":"A symmetric relation / back reference to the objectType that was signed. We are currently just modelling signing another signature (a chain) or signing a Revision (which can be a revision of a consent record, an agreement, policy etc)."}}></SchemaItem></div></details></SchemaItem></ul></details></TabItem></MimeTabs><div><div><ApiTabs label={undefined} id={undefined}><TabItem label={"200"} value={"200"}><div>

Consent record and signature created successfully

</div><details style={{"textAlign":"left","marginBottom":"1rem"}} className={"openapi-markdown__details"} data-collaposed={true} open={false}><summary style={{}}><strong>Response Headers</strong></summary><ul style={{"marginLeft":"1rem"}}></ul></details><div><MimeTabs className={"openapi-tabs__mime"} schemaType={"response"}><TabItem label={"application/json"} value={"application/json"}><SchemaTabs className={"openapi-tabs__schema"}><TabItem label={"Schema"} value={"Schema"}><details style={{}} className={"openapi-markdown__details response"} data-collapsed={false} open={true}><summary style={{}} className={"openapi-markdown__details-summary-response"}><strong>Schema</strong></summary><div style={{"textAlign":"left","marginLeft":"1rem"}}></div><ul style={{"marginLeft":"1rem"}}><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}} className={"openapi-markdown__details"}><summary style={{}}><span className={"openapi-schema__container"}><strong className={"openapi-schema__property"}>consentRecord</strong><span className={"openapi-schema__name"}> object</span></span></summary><div style={{"marginLeft":"1rem"}}><div style={{"marginTop":".5rem","marginBottom":".5rem"}}>

A consent record expresses consent (as defined in this building block's specification) to a single DataAgreement. There must be a UNIQUE constraint on (data agreement revision, individual)

</div><SchemaItem collapsible={false} name={"id"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"65471222e8c7c3bb3c2c9901","description":"Objects may be passed back by some API endpoints without an ID (PK), denoting that they are a \"draft\", i.e. a ConsentRecord that is not yet stored in the database and only exist in transit. Draft ConsentRecords do not have a Revision, but if paired up with a Signature, a valid Revision should be generated."}}></SchemaItem><SchemaItem collapsible={false} name={"dataAgreementId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","x-fk-model":"DataAgreement","description":"The DataAgreement to which consent has been given"}}></SchemaItem><SchemaItem collapsible={false} name={"dataAgreementRevisionId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","x-fk-model":"Revision","description":"The Revision of the data agreement which consent has been given to"}}></SchemaItem><SchemaItem collapsible={false} name={"dataAgreementRevisionHash"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"a1b2c3d4e5f6...","description":"Copy of the revision hash. The hash is the included in the signature and ensures against tampering with the original agreement."}}></SchemaItem><SchemaItem collapsible={false} name={"individualId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","x-fk-model":"Individual","description":"The Individual who has signed this consent record"}}></SchemaItem><SchemaItem collapsible={false} name={"optIn"} required={false} schemaName={"boolean"} qualifierMessage={undefined} schema={{"type":"boolean","format":"","example":true,"description":"True: The individual has positively opted in. False: The individual has explicitly said no (or withdrawn a previous consent)."}}></SchemaItem><SchemaItem collapsible={false} name={"state"} required={true} schemaName={"string"} qualifierMessage={"**Possible values:** [`unsigned`, `signed`]"} schema={{"type":"string","format":"","example":"signed","description":"The state field is used to record state changes after-the-fact. It is maintained by the Consent BB itself. Valid states: unsigned/pending more signatures/signed","enum":["unsigned","signed"]}}></SchemaItem><SchemaItem collapsible={false} name={"signatureId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","x-fk-model":"Signature","description":"A signature that hashes all the values of the consent record and has signed it with the key of the Invidiual, making it verifiable and tamper-proof. TBD: Relation to a Signature schema?"}}></SchemaItem><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}} className={"openapi-markdown__details"}><summary style={{}}><span className={"openapi-schema__container"}><strong className={"openapi-schema__property"}>sectorPreferences</strong><span className={"openapi-schema__name"}> object[]</span></span></summary><div style={{"marginLeft":"1rem"}}><li><div style={{"fontSize":"var(--ifm-code-font-size)","opacity":"0.6","marginLeft":"-.5rem","paddingBottom":".5rem"}}>Array [</div></li><SchemaItem collapsible={false} name={"sector"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"","description":"Name of the sector"}}></SchemaItem><SchemaItem collapsible={false} name={"optIn"} required={false} schemaName={"boolean"} qualifierMessage={undefined} schema={{"type":"boolean","description":"Defines sector is opted in or not"}}></SchemaItem><SchemaItem collapsible={false} name={"isLastUpdated"} required={false} schemaName={"boolean"} qualifierMessage={undefined} schema={{"type":"boolean","description":"Defines consent record for this sector is last updated"}}></SchemaItem><li><div style={{"fontSize":"var(--ifm-code-font-size)","opacity":"0.6","marginLeft":"-.5rem"}}>]</div></li></div></details></SchemaItem></div></details></SchemaItem><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}} className={"openapi-markdown__details"}><summary style={{}}><span className={"openapi-schema__container"}><strong className={"openapi-schema__property"}>revision</strong><span className={"openapi-schema__name"}> object</span></span></summary><div style={{"marginLeft":"1rem"}}><div style={{"marginTop":".5rem","marginBottom":".5rem"}}>

A *generic* revision model captures the serialised contents of any schema's single row. This is then subject to 1) cryptographic signature and 2) auditing.

Aside from the "successor" column, a revision should be considered locked.

</div><SchemaItem collapsible={false} name={"id"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"65471222e8c7c3bb3c2c6601","description":"Revision ID"}}></SchemaItem><SchemaItem collapsible={false} name={"schemaName"} required={true} schemaName={"string"} qualifierMessage={"**Possible values:** [`dataAgreement`, `policy`, `dataAgreementRecord`]"} schema={{"type":"string","format":"","example":"dataAgreement","description":"Previously \"schema\" but for technical reasons should be called \"schemaName\"","enum":["dataAgreement","policy","dataAgreementRecord"]}}></SchemaItem><SchemaItem collapsible={false} name={"objectId"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"65471222e8c7c3bb3c2c8492","description":"The PK of the object that was serialised"}}></SchemaItem><SchemaItem collapsible={false} name={"objectData"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"{...}","description":"The object that is serialised"}}></SchemaItem><SchemaItem collapsible={false} name={"signedWithoutObjectId"} required={false} schemaName={"boolean"} qualifierMessage={undefined} schema={{"type":"boolean","format":"","example":false,"description":"Indicates that objectId was left blank in serizalizedSnapshot when calculating serializedHash. objectId may subsequently be filled in."}}></SchemaItem><SchemaItem collapsible={false} name={"serizalizedSnapshot"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"{...}","description":"Revisioned data (sed as JSON) as a dict. Apply JSON Canonicalization Scheme as per IETF RFC 8785.  It contains all the fields of the schema except sucessorId, serializedHash, serializedSnapshot.\n"}}></SchemaItem><SchemaItem collapsible={false} name={"serializedHash"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2","description":"Hash of serizalizedSnapshot (SHA-1)"}}></SchemaItem><SchemaItem collapsible={false} name={"timestamp"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"2024-01-15T10:30:00Z","description":"Timestamp of when revisioning happened. It should be ISO 8601 UTC date time"}}></SchemaItem><SchemaItem collapsible={false} name={"authorizedByIndividualId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"description":"Individual ID","type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"authorizedByOtherId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"64541a2e6e7569000145ab00","description":"Reference to an admin user that has created this revision"}}></SchemaItem><SchemaItem collapsible={false} name={"successorId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"x-fk-model":"Revision","type":"string","description":"If this revision is no longer the latest revision, refer to its successor"}}></SchemaItem><SchemaItem collapsible={false} name={"predecessorHash"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3","description":"Tamper-resistent artifact from previous record, copied from serializedHash"}}></SchemaItem><SchemaItem collapsible={false} name={"predecessorSignature"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"c3d4e5f6a1b2...","description":"Tamper-resistent artifact from previous record (we don't know if the previous record was signed or not)"}}></SchemaItem></div></details></SchemaItem><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}} className={"openapi-markdown__details"}><summary style={{}}><span className={"openapi-schema__container"}><strong className={"openapi-schema__property"}>signature</strong><span className={"openapi-schema__name"}> object</span></span></summary><div style={{"marginLeft":"1rem"}}><div style={{"marginTop":".5rem","marginBottom":".5rem"}}>

A generic signature contains a cryptographic hash of some value,  together with a signature created by some private key in another system.  Required signing methods: Revision object or another Signature object.


</div><SchemaItem collapsible={false} name={"id"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"65471222e8c7c3bb3c2c5501","description":"Objects may be passed back by some API endpoints without an id (PK), denoting that they are a \"draft\", i.e. a Signature that is not yet stored in the database and only exists in transit."}}></SchemaItem><SchemaItem collapsible={false} name={"payload"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"{...}","description":"The final payload that is signed, constructed as a JSON serialisation of fields {verificationPayload: ..., verificationPayloadHash: ..., verificationMethod: ..., verificationArtifact: ..., verificationSignedBy: ..., verificationJwsHeader, timestamp: ..., signedWithoutObjectReference: ..., objectType: ..., objectReference: ...}. Serialised as a JSON dict. If the signature is generated before anything is stored in the database (and has a PK), then the objectReference should be omitted from the payload but filled in afterwards."}}></SchemaItem><SchemaItem collapsible={false} name={"signature"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"eyJhbGciOiJFZERTQSJ9...","description":"Signature of payload hash, the format of the signature should be specified by either verificationMethod or verificationJwsHeader"}}></SchemaItem><SchemaItem collapsible={false} name={"verificationMethod"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"Ed25519Signature2020","description":"A well-known string denoting which method is used. Valid values: TBD. This might be expanded with supported verification methods. There may be a minimal set of supported methods necessary."}}></SchemaItem><SchemaItem collapsible={false} name={"verificationPayload"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"{...}","description":"Internally generated serialised version of the data referenced by objectType and objectReference - by extracting and serialising their data as JSON"}}></SchemaItem><SchemaItem collapsible={false} name={"verificationPayloadHash"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"a1b2c3d4e5f6...","description":"Internally generated cryptographic hash of the value to be signed, i.e. the value of verificationPayload"}}></SchemaItem><SchemaItem collapsible={false} name={"verificationArtifact"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"","description":"A verification artifact in the form of a scanned object, image, signature etc"}}></SchemaItem><SchemaItem collapsible={false} name={"verificationSignedBy"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"did:key:z6Mkf...","description":"Because an identifier's information may change over time, there is a need to store that information at the time of signing. In the case of a cryptographic signature, this field should contain some identifier for looking up or verifying the public key of the signing party. In the case of a non-cryptographic signature, this field could contain a natural individual's names, personal number, email addresses - store a snapshot that binds to the signature at the time of signing. In the case of a cryptographic signature, this may be the fingerprint of the individual's public key or in some cases, a token from the user's ID session."}}></SchemaItem><SchemaItem collapsible={false} name={"verificationSignedAs"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"individual","description":"DRAFT FIELD: Specifies the relationship between the authorising signature and the invidual which the payload concerns. This is relevant for Consent Records. Possible values: \"individual\" / \"delegate\"."}}></SchemaItem><SchemaItem collapsible={false} name={"verificationJwsHeader"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"","description":"Alternative to the verificationMethod, verificationHash and verificationSignature, give a JWS serialised object (RFC7515)"}}></SchemaItem><SchemaItem collapsible={false} name={"timestamp"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"2024-01-15T10:30:00Z","description":"Timestamp of signature, currently this field isn't part of the payload so it's not tamper-proof"}}></SchemaItem><SchemaItem collapsible={false} name={"signedWithoutObjectReference"} required={false} schemaName={"boolean"} qualifierMessage={undefined} schema={{"type":"boolean","format":"","example":false,"description":"Indicates that objectReference was left blank in the serialised version that was signed"}}></SchemaItem><SchemaItem collapsible={false} name={"objectType"} required={false} schemaName={"string"} qualifierMessage={"**Possible values:** [`revision`, `signature`]"} schema={{"type":"string","format":"","example":"revision","description":"Name of the schema model that objectReference points to. Values: \"signature\" or \"revision\"","enum":["revision","signature"]}}></SchemaItem><SchemaItem collapsible={false} name={"objectReference"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","format":"","example":"65471222e8c7c3bb3c2c6601","description":"A symmetric relation / back reference to the objectType that was signed. We are currently just modelling signing another signature (a chain) or signing a Revision (which can be a revision of a consent record, an agreement, policy etc)."}}></SchemaItem></div></details></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n  \"consentRecord\": {\n    \"id\": \"65471222e8c7c3bb3c2c9901\",\n    \"dataAgreementId\": \"string\",\n    \"dataAgreementRevisionId\": \"string\",\n    \"dataAgreementRevisionHash\": \"a1b2c3d4e5f6...\",\n    \"individualId\": \"string\",\n    \"optIn\": true,\n    \"state\": \"signed\",\n    \"signatureId\": \"string\",\n    \"sectorPreferences\": [\n      {\n        \"sector\": \"\",\n        \"optIn\": true,\n        \"isLastUpdated\": true\n      }\n    ]\n  },\n  \"revision\": {\n    \"id\": \"65471222e8c7c3bb3c2c6601\",\n    \"schemaName\": \"dataAgreement\",\n    \"objectId\": \"65471222e8c7c3bb3c2c8492\",\n    \"objectData\": \"{...}\",\n    \"signedWithoutObjectId\": false,\n    \"serizalizedSnapshot\": \"{...}\",\n    \"serializedHash\": \"a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2\",\n    \"timestamp\": \"2024-01-15T10:30:00Z\",\n    \"authorizedByIndividualId\": \"string\",\n    \"authorizedByOtherId\": \"64541a2e6e7569000145ab00\",\n    \"successorId\": \"string\",\n    \"predecessorHash\": \"b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3\",\n    \"predecessorSignature\": \"c3d4e5f6a1b2...\"\n  },\n  \"signature\": {\n    \"id\": \"65471222e8c7c3bb3c2c5501\",\n    \"payload\": \"{...}\",\n    \"signature\": \"eyJhbGciOiJFZERTQSJ9...\",\n    \"verificationMethod\": \"Ed25519Signature2020\",\n    \"verificationPayload\": \"{...}\",\n    \"verificationPayloadHash\": \"a1b2c3d4e5f6...\",\n    \"verificationArtifact\": \"\",\n    \"verificationSignedBy\": \"did:key:z6Mkf...\",\n    \"verificationSignedAs\": \"individual\",\n    \"verificationJwsHeader\": \"\",\n    \"timestamp\": \"2024-01-15T10:30:00Z\",\n    \"signedWithoutObjectReference\": false,\n    \"objectType\": \"revision\",\n    \"objectReference\": \"65471222e8c7c3bb3c2c6601\"\n  }\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"400"} value={"400"}><div>

bad input parameter

</div><details style={{"textAlign":"left","marginBottom":"1rem"}} className={"openapi-markdown__details"} data-collaposed={true} open={false}><summary style={{}}><strong>Response Headers</strong></summary><ul style={{"marginLeft":"1rem"}}></ul></details><div></div></TabItem><TabItem label={"401"} value={"401"}><div>

Unauthorized

</div><details style={{"textAlign":"left","marginBottom":"1rem"}} className={"openapi-markdown__details"} data-collaposed={true} open={false}><summary style={{}}><strong>Response Headers</strong></summary><ul style={{"marginLeft":"1rem"}}></ul></details><div><MimeTabs className={"openapi-tabs__mime"} schemaType={"response"}><TabItem label={"application/json"} value={"application/json"}><SchemaTabs className={"openapi-tabs__schema"}><TabItem label={"Schema"} value={"Schema"}><details style={{}} className={"openapi-markdown__details response"} data-collapsed={false} open={true}><summary style={{}} className={"openapi-markdown__details-summary-response"}><strong>Schema</strong></summary><div style={{"textAlign":"left","marginLeft":"1rem"}}></div><ul style={{"marginLeft":"1rem"}}><SchemaItem collapsible={false} name={"errorCode"} required={true} schemaName={"integer"} qualifierMessage={undefined} schema={{"type":"integer","example":400}}></SchemaItem><SchemaItem collapsible={false} name={"errorDescription"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","example":"Bad input parameter"}}></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n  \"errorCode\": 400,\n  \"errorDescription\": \"Bad input parameter\"\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"500"} value={"500"}><div>

Internal server error

</div><details style={{"textAlign":"left","marginBottom":"1rem"}} className={"openapi-markdown__details"} data-collaposed={true} open={false}><summary style={{}}><strong>Response Headers</strong></summary><ul style={{"marginLeft":"1rem"}}></ul></details><div><MimeTabs className={"openapi-tabs__mime"} schemaType={"response"}><TabItem label={"application/json"} value={"application/json"}><SchemaTabs className={"openapi-tabs__schema"}><TabItem label={"Schema"} value={"Schema"}><details style={{}} className={"openapi-markdown__details response"} data-collapsed={false} open={true}><summary style={{}} className={"openapi-markdown__details-summary-response"}><strong>Schema</strong></summary><div style={{"textAlign":"left","marginLeft":"1rem"}}></div><ul style={{"marginLeft":"1rem"}}><SchemaItem collapsible={false} name={"errorCode"} required={true} schemaName={"integer"} qualifierMessage={undefined} schema={{"type":"integer","example":400}}></SchemaItem><SchemaItem collapsible={false} name={"errorDescription"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","example":"Bad input parameter"}}></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n  \"errorCode\": 400,\n  \"errorDescription\": \"Bad input parameter\"\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem></ApiTabs></div></div>
      