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

# Student Portfolio

> Allow students to curate a public portfolio page showcasing their credentials.

# Student Portfolio

Each student can have a public portfolio page — a curated display of their earned certificates, accessible via a unique URL. Institutions manage the page on behalf of students through the API.

***

## Portfolio page URL format

Portfolio pages are publicly accessible at:

```
https://portfolio.dokstamp.eu/{slug}
```

For example: `https://portfolio.dokstamp.eu/maria-fernanda-silva`

***

## Create a portfolio page

```bash theme={null}
curl -X POST "https://api.dokstamp.com/students/{student_uuid}/pages" \
  -H "Authorization: Bearer {TOKEN}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Tenant: {TENANT}" \
  -d '{
    "slug": "maria-fernanda-silva",
    "is_public": true,
    "bio": "Computer science graduate with a focus on distributed systems and machine learning."
  }'
```

The `slug` must be URL-friendly (lowercase letters, numbers, hyphens) and unique across the platform.

***

## Add certificates to the portfolio

After issuing certificates, add them to the student's portfolio page:

```bash theme={null}
curl -X POST "https://api.dokstamp.com/students/{student_uuid}/pages/{page_uuid}/items" \
  -H "Authorization: Bearer {TOKEN}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Tenant: {TENANT}" \
  -d '{
    "certificate_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "sort_order": 1,
    "is_visible": true
  }'
```

***

## Reorder portfolio items

```bash theme={null}
# Update sort_order to reposition an item
curl -X PATCH "https://api.dokstamp.com/students/{student_uuid}/pages/{page_uuid}/items/{item_uuid}" \
  -H "Authorization: Bearer {TOKEN}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Tenant: {TENANT}" \
  -d '{ "sort_order": 2 }'
```

***

## Hide a certificate from public view

Keep the item in the portfolio but make it invisible to public visitors:

```bash theme={null}
curl -X PATCH "https://api.dokstamp.com/students/{student_uuid}/pages/{page_uuid}/items/{item_uuid}" \
  -H "Authorization: Bearer {TOKEN}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Tenant: {TENANT}" \
  -d '{ "is_visible": false }'
```

***

## Set the page private

A private page is not accessible publicly. Useful while adding certificates before publishing:

```bash theme={null}
curl -X PATCH "https://api.dokstamp.com/students/{student_uuid}/pages/{page_uuid}" \
  -H "Authorization: Bearer {TOKEN}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Tenant: {TENANT}" \
  -d '{ "is_public": false }'
```

***

## Complete example — new graduate workflow

```javascript JavaScript theme={null}
async function onboardNewGraduate(student, certificate) {
  // 1. Create the portfolio page
  const pageRes = await api.post(`/students/${student.uuid}/pages`, {
    slug: slugify(`${student.name}-${Date.now()}`),
    is_public: false, // start private
    bio: `${student.name} graduated from ${certificate.course.name}.`,
  });
  const page = pageRes.data;

  // 2. Add the certificate
  await api.post(`/students/${student.uuid}/pages/${page.uuid}/items`, {
    certificate_uuid: certificate.uuid,
    sort_order: 1,
    is_visible: true,
  });

  // 3. Publish the page
  await api.patch(`/students/${student.uuid}/pages/${page.uuid}`, {
    is_public: true,
  });

  return `https://portfolio.dokstamp.eu/${page.slug}`;
}
```

***

## Portfolio privacy rules

| `is_public` | `is_visible` (item) | Result                             |
| ----------- | ------------------- | ---------------------------------- |
| `true`      | `true`              | Certificate visible on public page |
| `true`      | `false`             | Page public but certificate hidden |
| `false`     | any                 | Entire page is private             |
