diff --git a/developers/wallets/exchanges.md b/developers/wallets/exchanges.md
new file mode 100644
index 0000000..f3acb78
--- /dev/null
+++ b/developers/wallets/exchanges.md
@@ -0,0 +1,198 @@
+---
+layout: subpage
+title: "Handling a VC API Exchange in a Web Wallet"
+permalink: /developers/wallets/exchanges/
+---
+
+## {{ title }}
+
+
+
+A VC API workflow interaction begins with _either_ a CHAPI event or an
+interaction URL via a QR code (or similar user initiated transfer experience).
+
+The CHAPI event will provide a complete protocols object similar to the
+following:
+```json
+{
+ "protocols": {
+ "vcapi": "https://vcapi.example.com/workflows/abc/exchanges/123",
+ "OIC4VCI": "openid-credential-offer://?..."
+ }
+}
+```
+Alternatively, a QR code can be used to provide a URL which when dereferenced
+will result in either a `protocols` (object as above) or an HTML fallback page
+to allow the user to continue otherwise.
+
+To retrieve a `protocols` object from an _interaction URL_, the Wallet must send
+an HTTP GET request including an explicit `Accept: application/json` request
+header--which results in the same JSON object as above:
+
+```http
+GET /workflows/abc/exchanges/123/protocols
+Host: vcapi.example.com
+Accept: application/json
+
+{
+ "protocols": {
+ "vcapi": "https://vcapi.example.com/workflows/abc/exchanges/123",
+ "OIC4VCI": "openid-credential-offer://?..."
+ }
+}
+```
+
+Once a VC API exchange URL is acquisitioned from `protocols.vcapi`, a POST
+request is sent with a configuration object (which may be empty) to begin the
+exchange:
+
+```http
+POST /workflows/abc/exchanges/123
+Host: vcapi.example.com
+
+{}
+```
+
+A response will be returned by the exchanger...
+
+If the response object is empty (as above), the exchange is complete and nothing
+is requested from nor offered to the exchange client.
+
+If, however, the object includes `verifiablePresentationRequest`, then the
+exchange is not yet complete and some *additional information is requested*, as
+specified by the contents of the associated verifiable presentation request.
+
+> Read more about possible values in the
+> [Verifiable Presentation Requests](https://w3c-ccg.github.io/vp-request-spec/#overview)
+> specification.
+
+For example:
+```json
+{
+ "verifiablePresentationRequest": {
+ "query": [{
+ "type": "QueryByExample",
+ "credentialQuery": [{
+ "reason": "We require proof of residency to onboard you.",
+ "example": {
+ "@context": [
+ "https://www.w3.org/ns/credentials/v2",
+ "https://w3id.org/citizenship/v1"
+ ],
+ "type": "PermanentResidentCard"
+ }
+ }]
+ }]
+ }
+}
+```
+
+If the object includes `verifiablePresentation`, then some *information is
+offered*, such as verifiable credentials issued to the holder operating the
+exchange client (i.e. the Wallet) or verifiable credentials with information
+about the exchange server's operator based on the exchange client's request.
+
+For example:
+```json
+{
+ "verifiablePresentation": {
+ "@context": [
+ "https://www.w3.org/ns/credentials/v2"
+ ],
+ "type": ["VerifiablePresentation"],
+ "verifiableCredential": [{
+ "@context": [
+ "https://www.w3.org/ns/credentials/v2",
+ "https://w3id.org/citizenship/v1"
+ ],
+ "type": ["VerifiableCredential", "PermanentResidentCard"],
+ // additional properties...
+ }]
+ }
+}
+```
+
+If the object includes `redirectUrl`, the *exchange is complete* and the
+workflow service recommends that the client sent the user to another place to
+continue the interaction.
+
+For example:
+```json
+{
+ "redirectUrl": "https://vcapi.example.com/go-here-next"
+}
+```
+
+Many Verifiable Credential use cases can be implemented using these basic
+primitives. Either party to an exchange is capable of requesting Verifiable
+Presentations and of providing one or more Verifiable Credentials that might be
+necessary to establish trust and/or gain authorization capabilities, and either
+party is capable of presenting credentials that they hold or that they have
+issued. Specific workflows can be configured to expect specific presentations
+and credentials and to reject deviations from the expected flow of information.
+
+When a workflow service determines that a particular message is not acceptable,
+it raises an error by responding with a `4xx` HTTP status message and a JSON
+object that expresses information about the error.
+
+Below is an example of a typical exchange:
+
+```mermaid
+sequenceDiagram
+ participant H as Holder
+ participant W as Holder Coordinator (Wallet)
+ participant I as Issuer/Verifier Coordinator
+ autonumber
+ Note right of H: Start exchange
+ W->>I: Initiate
+ Note right of W: POST /workflows/abc/exchanges/123 — HTTP request to start exchange (e.g., send credentials, get credentials)
+ I->>W: Verifiable Presentation Request (VPR)
+ Note left of I: VPR includes method of interaction, for purposes of exchange
+ W->>I: Verifiable Presentation (VP)
+ Note right of W: POST /workflows/abc/exchanges/123 — sent via interaction mechanism to meet requirements of exchange
+ I->>W: Verifiable Presentation
+ Note left of I: VP includes result of exchange (e.g., VCs), or VPR with new interaction request, or error description
+```
+
+The exchange client (Wallet) code for a flow like the above may look similar to
+the following:
+
+```js
+const receivedExchangeUrl = 'https://vcapi.example.com/workflows/abc/exchanges/123';
+
+const response = await fetch(receivedExchangeUrl, {
+ method: 'POST'
+ body: JSON.stringify({})
+});
+const body = await response.json();
+
+function checkResponse(body) {
+ if('verifiablePresentationRequest' in body) {
+ // use the information in the Verifiable Presentation Request to find a
+ // credential that fulfills the request, then send a Verifiable
+ // Presentation a message back to the exchange endpoint
+ // Verifiable Presentation Request
+ const verifiablePresentation = findCredentialAndCreatePresentation();
+ const response = await fetch(receivedExchangeUrl, {
+ method: 'POST',
+ body: JSON.stringify({verifiablePresentation})
+ });
+ checkResponse(response.json());
+ }
+ if('verifiablePresentation' in body) {
+ // the Wallet has received a Verifiable Presentation containing one or more
+ // Verifiable Credentials--use them per your use case
+ }
+ if('redirectUrl' in body) {
+ // take the user to the new location
+ }
+}
\ No newline at end of file
diff --git a/developers/wallets/index.md b/developers/wallets/index.md
index a8a7c41..c151252 100644
--- a/developers/wallets/index.md
+++ b/developers/wallets/index.md
@@ -12,6 +12,7 @@ CHAPI integrates easily into digital wallet software, allowing your wallet to re
* [Verifiable Credential Storage](#verifiable-credential-storage)
* [Verifiable Credential Presentation](#verifiable-credential-presentation)
* [DID Authentication with CHAPI](#did-authentication-with-chapi)
+* new! [Handling VC API Exchanges](exchanges/)
## Native Wallets
* [Wallet Registration](native/#wallet-registration)