---
title: Update a certificate
description: Patch certificate settings, attributes, and metadata
method: PATCH
path: /api/v1/workspaces/{slug}/certificates/{id}
group: Certificates
scopes: certificates:write
---

# Update a certificate

# Update a certificate

Partial update. Omitted fields keep their current values.

## Authorization

```http
Authorization: Bearer vc_...
```

Requires `certificates:write` (or full access) and an active Pro seat.

## Path parameters

  
- `slug*` string — Workspace slug Example: `acme`.

  
- `id*` UUID — Certificate id Example: `550e8400-e29b-41d4-a716-446655440000`.

## Body parameters

All fields optional. Notable ones:

  
- `name?` string — Certificate name Example: `Python Fundamentals`.

  
- `status?` string — `draft`, `active`, or `archived`. Cannot return to `draft` after leaving it Example: `active`.

  
- `attributes?` array — Attribute definitions: objects with `key` and `label` Example: `[{ "key": "course", "label": "Course" }]`.

  
- `validity_days?` integer | null — Default validity for new issues; `null` clears expiry; omit to keep Example: `365`.

  
- `request_form_enabled?` boolean — Enable the public certificate request form Example: `true`.

  
- `request_form_mode?` string — `auto_issue_all` or `manual_approval`. Releasing someone already on the recipient list is the unlock form's job, not a request mode. Example: `manual_approval`.

  
- `unlock_form_enabled?` boolean — Hold imported recipients behind an unlock form. Enabling invites every pending recipient; disabling revokes outstanding links. Example: `true`.

  
- `correction_form_enabled?` boolean — Enable correction form Example: `true`.

  
- `correction_form_mode?` string — Correction form mode Example: `manual_approval`.

  
- `description?` string — Description (max 4000 chars) Example: `Completion of the Python fundamentals track`.

  
- `certificate_type?` string — Allowed type, or empty string to clear Example: `course`.

  
- `level?` string — Allowed level, or empty string to clear Example: `beginner`.

  
- `duration?` string — Free text, or empty string to clear Example: `8 weeks`.

  
- `learn_more_url?` string — URL, or empty string to clear Example: `https://example.com/python`.

  
- `earning_criteria?` string[] — Criteria list Example: `["Complete all modules"]`.

  
- `skill_ids?` UUID[] — Replace linked skills; empty array clears; omit to keep

Form field types: `text`, `textarea`, `phone_number`, `single_select`, `multi_select`, `image`, `attachment`. Select fields need `options`.

## Request

```bash
curl -X PATCH \
  https://api.verifycate.com/api/v1/workspaces/acme/certificates/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer vc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "active",
    "validity_days": 365,
    "attributes": [
      { "key": "course", "label": "Course" },
      { "key": "roll_number", "label": "Roll number" }
    ]
  }'
```

```javascript
const id = "550e8400-e29b-41d4-a716-446655440000";
const res = await fetch(
  `https://api.verifycate.com/api/v1/workspaces/acme/certificates/${id}`,
  {
    method: "PATCH",
    headers: {
      Authorization: "Bearer vc_your_api_key",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      status: "active",
      validity_days: 365,
      attributes: [
        { key: "course", label: "Course" },
        { key: "roll_number", label: "Roll number" },
      ],
    }),
  },
);
```

```go
body := strings.NewReader(`{
  "status": "active",
  "validity_days": 365
}`)
req, _ := http.NewRequest(
	"PATCH",
	"https://api.verifycate.com/api/v1/workspaces/acme/certificates/550e8400-e29b-41d4-a716-446655440000",
	body,
)
req.Header.Set("Authorization", "Bearer vc_your_api_key")
req.Header.Set("Content-Type", "application/json")
```

```python
import json
import urllib.request

payload = json.dumps({"status": "active", "validity_days": 365}).encode()
req = urllib.request.Request(
    "https://api.verifycate.com/api/v1/workspaces/acme/certificates/550e8400-e29b-41d4-a716-446655440000",
    data=payload,
    method="PATCH",
    headers={
        "Authorization": "Bearer vc_your_api_key",
        "Content-Type": "application/json",
    },
)
with urllib.request.urlopen(req) as res:
    print(res.read().decode())
```

## Response schema

- `active_recipient_count*` integer — 
- `attributes*` object — 
- `blockchain_enabled*` boolean — 
- `certificate_type*` string — 
- `correction_form_enabled*` boolean — 
- `correction_form_fields*` array — 
- `correction_form_mode*` string — 
- `correction_form_token*` string — 
- `created_at*` string — 
- `description*` string — 
- `duration*` string — 
- `earning_criteria*` object — 
- `has_template*` boolean — 
- `id*` string — 
- `learn_more_url*` string — 
- `level*` string — 
- `name*` string — 
- `pending_recipient_count*` integer — 
- `published_template_version?` integer — 
- `recipient_status_counts?` RecipientStatusCounts — 
  - `awaiting_form_response*` integer — 
  - `awaiting_review*` integer — 
  - `changes_requested*` integer — 
  - `expired*` integer — 
  - `issued*` integer — 
  - `ready_to_send*` integer — 
  - `waiting_for_publish*` integer — 
- `request_form_enabled*` boolean — 
- `request_form_fields*` array — 
- `request_form_mode*` string — 
- `request_form_token*` string — 
- `skills*` array — 
- `sponsors*` array — 
- `status*` string — 
- `template_versions?` array — 
- `unlock_form_enabled*` boolean — 
- `unlock_form_fields*` array — 
- `unlock_release_policy?` string — 
- `updated_at*` string — 
- `validity_days*` integer — 
- `workspace_id*` string — 

## Response

### 200

Updated certificate (same shape as get).

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Python Fundamentals",
  "status": "active",
  "validity_days": 365,
  "attributes": [
    { "key": "course", "label": "Course" },
    { "key": "roll_number", "label": "Roll number" }
  ],
  "skills": [],
  "has_template": true,
  "pending_recipient_count": 0,
  "active_recipient_count": 0
}
```

### 400

```json
{
  "title": "Bad Request",
  "status": 400,
  "detail": "a certificate cannot return to draft after it has been issued",
  "code": "status_locked"
}
```

Form fields are edited through the [Forms endpoints](/docs/api/forms/update), not here.
