---
id: send-open-id-conformance-credential-offer
title: "Send conformance credential offer"
description: "Sends a credential offer of a conformance credential definition to the `credential_offer_endpoint` of a running test of the conformance suite. Use it in the issuer test plans that start with an offer of the issuer (issuer initiated): the suite waits for the offer at the endpoint that the test shows."
sidebar_label: "Send conformance credential offer"
hide_title: true
hide_table_of_contents: true
api: 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
sidebar_class_name: "post api-method"
info_path: docs/extensions-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"}>Send conformance credential offer</h1>

<MethodEndpoint method={"post"} path={"/v4/config/platform/extension/openid-conformance/credential-offer"}></MethodEndpoint>



Sends a credential offer of a conformance credential definition to the `credential_offer_endpoint` of a running test of the conformance suite. Use it in the issuer test plans that start with an offer of the issuer (issuer initiated): the suite waits for the offer at the endpoint that the test shows.

The wallet makes the offer with the claims of the conformance test user and sends it to the endpoint. The answer holds the issuance history of the offer and the HTTP status that the suite answered. Only the credential definitions of the extension can be sent (`sdJwtPidCredentialDefinitionId`, `mdocPidCredentialDefinitionId`, `mdocMdlCredentialDefinitionId` or `mdocPhotoIdCredentialDefinitionId` of [Read OpenID Conformance extension](/docs/extensions-api/read-open-id-conformance-extension)).

The answer is `404` when the extension is not `enabled`.


## Request

<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><strong className={"openapi-schema__required"}>required</strong></summary><div style={{"textAlign":"left","marginLeft":"1rem"}}></div><ul style={{"marginLeft":"1rem"}}><SchemaItem collapsible={false} name={"credentialDefinitionId"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","description":"A credential definition of the extension."}}></SchemaItem><SchemaItem collapsible={false} name={"credentialOfferEndpoint"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","description":"The `credential_offer_endpoint` of the running test. The wallet sends the offer only to an `https` URL with no query, and refuses an address of a private network."}}></SchemaItem></ul></details></TabItem></MimeTabs><div><div><ApiTabs label={undefined} id={undefined}><TabItem label={"200"} value={"200"}><div>

The offer is sent.

</div><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={"credentialExchangeId"} required={true} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","description":"The issuance history of the offer. Read it with the issuance history of the OpenID4VC API."}}></SchemaItem><SchemaItem collapsible={false} name={"credentialOfferEndpointStatus"} required={true} schemaName={"integer"} qualifierMessage={undefined} schema={{"type":"integer","description":"The HTTP status that the conformance suite answered to the offer."}}></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n  \"credentialExchangeId\": \"string\",\n  \"credentialOfferEndpointStatus\": 0\n}"} language={"json"}></ResponseSamples></TabItem><TabItem label={"Example"} value={"Example"}><ResponseSamples responseExample={"{\n  \"credentialExchangeId\": \"3b1d0b0e-5d0c-4b2a-9f53-2f1c9a7e5c41\",\n  \"credentialOfferEndpointStatus\": 200\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"400"} value={"400"}><div>

Bad request. The `Content-Type` is not `application/json` (`Content type must be JSON`), the body is not valid JSON or has another member (`Invalid content`), a member is empty (`credentialDefinitionId must not be empty`, `credentialOfferEndpoint must not be empty`), the credential definition is not one of the extension (`Only the credential definitions of the OpenID Conformance extension can be sent to the test suite`), or the organisation or its wallet is not found. A refusal of the wallet, for example of the endpoint, keeps the status and the text of the wallet.

</div><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><SchemaItem collapsible={false} name={"errorKey"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","description":"A text code of the refusal that does not change when the text changes. Only some refusals have it, for example `organisation_suspended`, `feature_disabled` or `purpose_exists`."}}></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n  \"errorCode\": 400,\n  \"errorDescription\": \"Bad input parameter\",\n  \"errorKey\": \"string\"\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"401"} value={"401"}><div>

The API key is missing or not valid.

</div><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><SchemaItem collapsible={false} name={"errorKey"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","description":"A text code of the refusal that does not change when the text changes. Only some refusals have it, for example `organisation_suspended`, `feature_disabled` or `purpose_exists`."}}></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n  \"errorCode\": 400,\n  \"errorDescription\": \"Bad input parameter\",\n  \"errorKey\": \"string\"\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"404"} value={"404"}><div>

The extension is not `enabled` (`Extension 'openidConformance' is not enabled for organisation '<organisationId>'`).

</div><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><SchemaItem collapsible={false} name={"errorKey"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","description":"A text code of the refusal that does not change when the text changes. Only some refusals have it, for example `organisation_suspended`, `feature_disabled` or `purpose_exists`."}}></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n  \"errorCode\": 400,\n  \"errorDescription\": \"Bad input parameter\",\n  \"errorKey\": \"string\"\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"500"} value={"500"}><div>

Internal server error.

</div><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><SchemaItem collapsible={false} name={"errorKey"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","description":"A text code of the refusal that does not change when the text changes. Only some refusals have it, for example `organisation_suspended`, `feature_disabled` or `purpose_exists`."}}></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n  \"errorCode\": 400,\n  \"errorDescription\": \"Bad input parameter\",\n  \"errorKey\": \"string\"\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"502"} value={"502"}><div>

The wallet cannot be reached (`Failed to reach the wallet`).

</div><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><SchemaItem collapsible={false} name={"errorKey"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","description":"A text code of the refusal that does not change when the text changes. Only some refusals have it, for example `organisation_suspended`, `feature_disabled` or `purpose_exists`."}}></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n  \"errorCode\": 400,\n  \"errorDescription\": \"Bad input parameter\",\n  \"errorKey\": \"string\"\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"504"} value={"504"}><div>

The wallet did not answer in time (`The wallet did not answer in time`).

</div><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><SchemaItem collapsible={false} name={"errorKey"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string","description":"A text code of the refusal that does not change when the text changes. Only some refusals have it, for example `organisation_suspended`, `feature_disabled` or `purpose_exists`."}}></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n  \"errorCode\": 400,\n  \"errorDescription\": \"Bad input parameter\",\n  \"errorKey\": \"string\"\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem></ApiTabs></div></div>
      