> ## Documentation Index
> Fetch the complete documentation index at: https://docs.baanx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Revoke Consent

> Revoke a specific consent while maintaining immutable audit trail

## Overview

Revokes a specific consent for a user. This operation creates a **new consent record** with `revoked` status while preserving the original consent record for audit purposes.

<Warning>
  Revoking required consents (e.g., `termsAndPrivacy`) will change the user's overall consent status to `incomplete`, potentially restricting their access to features.
</Warning>

## Endpoint

```
DELETE https://api.baanx.com/v2/consent/consentSet/{consentSetId}/consent/{consentId}
```

## Headers

| Header         | Required | Description                         |
| -------------- | -------- | ----------------------------------- |
| `x-client-key` | ✅        | Your public API key                 |
| `x-secret-key` | ✅        | Your secret API key                 |
| `x-us-env`     | ❌        | Set to `true` for US region routing |

## Path Parameters

| Parameter      | Type          | Required | Description                                    |
| -------------- | ------------- | -------- | ---------------------------------------------- |
| `consentSetId` | string (UUID) | ✅        | UUID of the consent set containing the consent |
| `consentId`    | string (UUID) | ✅        | UUID of the specific consent to revoke         |

## Response

### 200 OK

```json theme={null}
{
  "consentId": "consent_new_revoked_001",
  "consentSetId": "550e8400-e29b-41d4-a716-446655440001",
  "consentType": "marketingNotifications",
  "consentStatus": "revoked",
  "revocationTimestamp": "2024-01-20T14:22:00Z",
  "_links": {
    "consentSet": {
      "href": "https://api.baanx.com/v2/consent/consentSet/550e8400-e29b-41d4-a716-446655440001",
      "method": "GET"
    },
    "audit": {
      "href": "https://api.baanx.com/v2/consent/user/user_123abc456def/audit",
      "method": "GET"
    }
  }
}
```

<Info>
  **New Consent Record**: Notice the `consentId` in the response is different from the request. Revocation creates a new record, preserving the original for audit compliance.
</Info>

### 404 Not Found

```json theme={null}
{
  "error": "Not found",
  "details": [
    "Consent with ID 'consent_123' not found in consent set"
  ]
}
```

**Possible Causes:**

* Consent ID doesn't exist
* Consent already revoked
* Wrong consent set ID

### 498 Invalid Client Key

```json theme={null}
{
  "error": "Invalid client key",
  "details": [
    "The provided x-client-key is invalid or expired"
  ]
}
```

### 499 Missing Client Key

```json theme={null}
{
  "error": "Missing client key",
  "details": [
    "x-client-key header is required for all requests"
  ]
}
```

## Code Examples

### TypeScript

```typescript theme={null}
async function revokeConsent(consentSetId: string, consentId: string) {
  const response = await fetch(
    `https://api.baanx.com/v2/consent/consentSet/${consentSetId}/consent/${consentId}`,
    {
      method: 'DELETE',
      headers: {
        'x-client-key': process.env.BAANX_CLIENT_KEY!,
        'x-secret-key': process.env.BAANX_SECRET_KEY!
      }
    }
  );

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Revocation failed: ${error.details.join(', ')}`);
  }

  return response.json();
}

const result = await revokeConsent(
  '550e8400-e29b-41d4-a716-446655440001',
  'consent_002'
);

console.log(`Consent ${result.consentType} revoked at ${result.revocationTimestamp}`);
```

### TypeScript - Revoke by Type

```typescript theme={null}
async function revokeConsentByType(
  userId: string,
  consentType: string
) {
  const { consentSets } = await getUserConsentStatus(userId, true);
  const consentSet = consentSets[0];

  const targetConsent = consentSet.consents.find(
    c => c.consentType === consentType && c.consentStatus === 'granted'
  );

  if (!targetConsent) {
    throw new Error(`No granted consent found for type: ${consentType}`);
  }

  return await revokeConsent(consentSet.consentSetId, targetConsent.consentId);
}

await revokeConsentByType('user_123abc456def', 'marketingNotifications');
```

### Python

```python theme={null}
import requests

def revoke_consent(consent_set_id, consent_id):
    response = requests.delete(
        f'https://api.baanx.com/v2/consent/consentSet/{consent_set_id}/consent/{consent_id}',
        headers={
            'x-client-key': os.getenv('BAANX_CLIENT_KEY'),
            'x-secret-key': os.getenv('BAANX_SECRET_KEY')
        }
    )

    response.raise_for_status()
    return response.json()

result = revoke_consent(
    '550e8400-e29b-41d4-a716-446655440001',
    'consent_002'
)

print(f"Revoked {result['consentType']} at {result['revocationTimestamp']}")
```

### cURL

```bash theme={null}
curl -X DELETE "https://api.baanx.com/v2/consent/consentSet/550e8400-e29b-41d4-a716-446655440001/consent/consent_002" \
  -H "x-client-key: your_client_key" \
  -H "x-secret-key: your_secret_key"
```

## Use Cases

<AccordionGroup>
  <Accordion title="User Privacy Settings">
    Allow users to opt-out of marketing:

    ```typescript theme={null}
    async function handleMarketingOptOut(userId: string) {
      try {
        await revokeConsentByType(userId, 'marketingNotifications');

        return {
          success: true,
          message: 'You have been unsubscribed from marketing communications'
        };
      } catch (error) {
        return {
          success: false,
          message: 'Failed to update preferences'
        };
      }
    }
    ```
  </Accordion>

  <Accordion title="Right to Be Forgotten (GDPR)">
    Revoke all consents for account deletion:

    ```typescript theme={null}
    async function initiateAccountDeletion(userId: string) {
      const { consentSets } = await getUserConsentStatus(userId, true);

      for (const consentSet of consentSets) {
        for (const consent of consentSet.consents) {
          if (consent.consentStatus === 'granted') {
            await revokeConsent(consentSet.consentSetId, consent.consentId);
          }
        }
      }

      const audit = await getConsentAudit(userId, 1000, 0);
      await archiveForLegalHold(userId, audit);

      return { message: 'All consents revoked, account marked for deletion' };
    }
    ```
  </Accordion>

  <Accordion title="Consent Management UI">
    Build interactive consent toggles:

    ```typescript theme={null}
    function ConsentToggle({ consent, consentSetId, onRevoke }) {
      const handleToggle = async () => {
        if (consent.consentStatus === 'granted') {
          await revokeConsent(consentSetId, consent.consentId);
          onRevoke();
        }
      };

      return (
        <Toggle
          checked={consent.consentStatus === 'granted'}
          onChange={handleToggle}
          disabled={consent.consentType === 'termsAndPrivacy'}
        >
          {getConsentLabel(consent.consentType)}
        </Toggle>
      );
    }
    ```
  </Accordion>

  <Accordion title="Compliance-Driven Revocation">
    Revoke consent based on policy updates:

    ```typescript theme={null}
    async function revokeOutdatedConsents(userId: string, cutoffDate: string) {
      const { consentSets } = await getUserConsentStatus(userId, true);

      const outdatedConsents = consentSets[0].consents.filter(
        c => c.createdAt < cutoffDate && c.consentStatus === 'granted'
      );

      for (const consent of outdatedConsents) {
        await revokeConsent(consentSets[0].consentSetId, consent.consentId);
      }

      return {
        revoked: outdatedConsents.length,
        message: 'Outdated consents revoked, user must re-consent'
      };
    }
    ```
  </Accordion>
</AccordionGroup>

## Impact on Consent Status

Revoking consents affects the user's overall consent status:

| Revoked Consent Type                                                              | Impact                                       | User Status Change                                               |
| --------------------------------------------------------------------------------- | -------------------------------------------- | ---------------------------------------------------------------- |
| **Required** (`termsAndPrivacy`, `eSignAct` for US policy)                        | User loses access to core features           | `complete` → `incomplete`                                        |
| **Optional** (`marketingNotifications`, `emailNotifications`, `smsNotifications`) | User stops receiving optional communications | Status remains `complete` if all required consents still granted |

<Warning>
  Always check the user's consent status after revocation to determine if access restrictions should be applied.
</Warning>

## Best Practices

<AccordionGroup>
  <Accordion title="Verify Before Revoking">
    Check if consent is already revoked:

    ```typescript theme={null}
    async function safeRevokeConsent(consentSetId: string, consentId: string) {
      const consentSet = await getConsentSetById(consentSetId);
      const consent = consentSet.consents.find(c => c.consentId === consentId);

      if (!consent) {
        throw new Error('Consent not found');
      }

      if (consent.consentStatus === 'revoked') {
        console.log('Consent already revoked');
        return consent;
      }

      return await revokeConsent(consentSetId, consentId);
    }
    ```
  </Accordion>

  <Accordion title="Notify Users">
    Send confirmation after revocation:

    ```typescript theme={null}
    async function revokeWithNotification(userId: string, consentType: string) {
      const result = await revokeConsentByType(userId, consentType);

      await sendEmail(userId, {
        subject: 'Privacy Preferences Updated',
        body: `Your consent for ${consentType} has been revoked as requested.`
      });

      return result;
    }
    ```
  </Accordion>

  <Accordion title="Handle Dependencies">
    Warn users about feature impacts:

    ```typescript theme={null}
    function getRevocationImpact(consentType: string): string[] {
      const impacts = {
        termsAndPrivacy: ['Account access will be restricted', 'Must re-consent to continue'],
        marketingNotifications: ['No marketing emails'],
        emailNotifications: ['No email notifications for account activity'],
        smsNotifications: ['No SMS notifications']
      };

      return impacts[consentType] || [];
    }

    async function revokeWithWarning(userId: string, consentType: string) {
      const impacts = getRevocationImpact(consentType);

      return {
        impacts,
        proceed: async () => await revokeConsentByType(userId, consentType)
      };
    }
    ```
  </Accordion>

  <Accordion title="Log Revocations">
    Track revocation requests:

    ```typescript theme={null}
    async function revokeWithLogging(
      consentSetId: string,
      consentId: string,
      reason: string
    ) {
      logger.info('Consent revocation initiated', {
        consentSetId,
        consentId,
        reason,
        timestamp: new Date().toISOString()
      });

      try {
        const result = await revokeConsent(consentSetId, consentId);

        logger.info('Consent revoked successfully', {
          newConsentId: result.consentId,
          consentType: result.consentType
        });

        return result;
      } catch (error) {
        logger.error('Consent revocation failed', { error: error.message });
        throw error;
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Get User Consent Status" icon="circle-check" href="/api-reference/consent/get-user-consent">
    Check consent status after revocation
  </Card>

  <Card title="Get Consent Audit Trail" icon="clock-rotate-left" href="/api-reference/consent/get-consent-audit">
    View revocation in audit history
  </Card>

  <Card title="Get Consent Set" icon="magnifying-glass" href="/api-reference/consent/get-consent-set">
    Retrieve consent set details
  </Card>

  <Card title="Compliance Guide" icon="clipboard-check" href="/guides/consent/compliance">
    GDPR/CCPA compliance best practices
  </Card>
</CardGroup>
