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

# Workflows

> Step-by-step instructions for the most common Certiva operator tasks.

## Issue a single credential

<Steps>
  <Step title="Authenticate">
    ```bash theme={null}
    curl -X POST https://api.certiva.io/api/auth/login \
      -H "Content-Type: application/json" \
      -d '{"username": "admin", "password": "your-password"}'
    ```

    ```json theme={null}
    { "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }
    ```

    <Tip>
      The API also sets an `httpOnly` cookie (`certiva_access_token`). Dashboard requests use the cookie automatically — no manual header needed.
    </Tip>
  </Step>

  <Step title="Submit the credential">
    ```bash theme={null}
    curl -X POST https://api.certiva.io/api/credentials \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer <accessToken>" \
      -d '{
        "studentName": "Siti Rahayu",
        "studentId": "2020045678",
        "degree": "Bachelor of Computer Science",
        "graduationYear": 2024
      }'
    ```

    ```json theme={null}
    {
      "id": "clx9k2...",
      "verificationId": "vrf_2f9a0cdbe7c1",
      "verificationCode": "CERT-A1B2C3",
      "verificationUrl": "https://certiva.io/verify/vrf_2f9a0cdbe7c1",
      "qrCodeUri": "https://api.certiva.io/api/credentials/<id>/qr",
      "anchorStatus": "PENDING",
      "issuedAt": "2024-06-01T08:00:00.000Z"
    }
    ```
  </Step>

  <Step title="Share with the recipient">
    Give the credential holder the `verificationCode`, `verificationUrl`, or QR code. All three resolve to the same credential record.
  </Step>
</Steps>

## Issue credentials in bulk (CSV)

<Steps>
  <Step title="Upload the CSV">
    ```bash theme={null}
    curl -X POST https://api.certiva.io/api/credentials/bulk \
      -H "Authorization: Bearer <accessToken>" \
      -F "file=@credentials.csv"
    ```

    ```json theme={null}
    {
      "batchId": "batch_8f3c...",
      "status": "QUEUED",
      "totalRows": 250
    }
    ```
  </Step>

  <Step title="Poll batch progress">
    ```bash theme={null}
    curl https://api.certiva.io/api/batches/batch_8f3c... \
      -H "Authorization: Bearer <accessToken>"
    ```

    ```json theme={null}
    {
      "batchId": "batch_8f3c...",
      "status": "PROCESSING",
      "totalRows": 250,
      "processedRows": 143,
      "failedRows": 2
    }
    ```

    Poll until `status` is `COMPLETED` or `FAILED`. Failed rows include per-row error details.
  </Step>
</Steps>

## Verify a credential publicly

No authentication required for any verification endpoint.

### By verification code

```bash theme={null}
curl -X POST https://api.certiva.io/api/verify/credential/code \
  -H "Content-Type: application/json" \
  -d '{"verificationCode": "CERT-A1B2C3"}'
```

```json theme={null}
{
  "verificationMode": "CORE_REGISTRY",
  "result": "VALID",
  "revoked": false,
  "degree": "Bachelor of Computer Science",
  "issuedAt": "2024-06-01T08:00:00.000Z",
  "issuer": { "name": "Universitas Contoh", "status": "ACTIVE" },
  "blockchainVerified": true,
  "txHash": "0x3a7f2e...c4d1b8",
  "blockNumber": 14203847,
  "anchoredAt": "2024-06-01T08:04:12.000Z"
}
```

### By PDF upload

```bash theme={null}
curl -X POST https://api.certiva.io/api/verify/credential/pdf \
  -F "file=@credential.pdf"
```

Rate limited to 10 requests per 60 seconds.

## Register a document integrity proof

<Steps>
  <Step title="Upload the document">
    ```bash theme={null}
    curl -X POST https://api.certiva.io/api/document-proofs \
      -H "Authorization: Bearer <accessToken>" \
      -F "file=@transcript.pdf"
    ```

    ```json theme={null}
    {
      "id": "dp_7a3f...",
      "verificationCode": "DOC-X9Y8Z7",
      "qrCodeUri": "https://api.certiva.io/api/document-proofs/dp_7a3f.../qr"
    }
    ```

    Certiva hashes the document and discards the source file. Only the SHA-256 hash is stored.
  </Step>

  <Step title="Share the verification code">
    Give document holders the `verificationCode` or QR code. Anyone can verify the document has not been modified.
  </Step>
</Steps>

## Verify a document proof publicly

```bash theme={null}
curl -X POST https://api.certiva.io/api/document-proofs/verify/document \
  -F "file=@transcript.pdf" \
  -F "code=DOC-X9Y8Z7"
```

```json theme={null}
{
  "result": "VALID",
  "verificationMode": "SECURE_PDF"
}
```

Returns `VALID` on a byte-level hash match, `INVALID` if the file has been modified, or `NOT_FOUND` if no matching proof exists.

## Revoke a credential

```bash theme={null}
curl -X PATCH https://api.certiva.io/api/credentials/<id>/revoke \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <accessToken>" \
  -d '{"reason": "DATA_CORRECTION"}'
```

Valid reasons: `DATA_CORRECTION`, `ISSUED_IN_ERROR`, `FRAUD_SUSPECTED`, `INSTITUTION_REQUEST`, `OTHER`, `LEGACY`.

After revocation, public verification returns `result: REVOKED` permanently.

## Bulk revoke

```bash theme={null}
curl -X POST https://api.certiva.io/api/credentials/bulk-revoke \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <accessToken>" \
  -d '{
    "ids": ["clx9k2...", "clx9k3..."],
    "reason": "INSTITUTION_REQUEST"
  }'
```

## Create an admin account

Requires `OWNER` or `SUPER_ADMIN` role.

```bash theme={null}
curl -X POST https://api.certiva.io/api/auth/register \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <accessToken>" \
  -d '{
    "username": "auditor1",
    "password": "strong-password-here",
    "role": "AUDITOR"
  }'
```

## Migrate assets from local storage to R2

A one-time migration script moves all credential assets from the local filesystem driver to Cloudflare R2. Run this once during the transition to staging or production:

```bash theme={null}
cd apps/api
npx tsx scripts/migrate-assets-to-r2.ts
```

<Warning>
  Run in a maintenance window with valid R2 credentials configured. Verify all assets are present in R2 before switching `STORAGE_DRIVER=r2` in production.
</Warning>

## Rebuild credential assets

If QR codes or metadata become stale after a URL configuration change:

```bash theme={null}
curl -X POST https://api.certiva.io/api/credentials/<id>/rebuild-assets \
  -H "Authorization: Bearer <accessToken>"
```

## Export audit logs

```bash theme={null}
curl https://api.certiva.io/api/audit/dashboard/export \
  -H "Authorization: Bearer <accessToken>"
```
