# Brands

Source: https://opvs.ai/docs/api/brands

## `GET` /api/v1/brands

**List Brands**

List all brands the current user belongs to.

**Parameters**

- `format` (query, any, optional) — Response format: yaml or md

```bash
curl -X GET 'https://app.opvs.ai/api/v1/brands' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/brands",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/brands", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/brands/{brand_id}

**Get Brand**

Get brand details. Requires membership.

**Parameters**

- `brand_id` (path, integer, required)
- `format` (query, any, optional) — Response format: yaml or md

```bash
curl -X GET 'https://app.opvs.ai/api/v1/brands/{brand_id}' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/brands/{brand_id}",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/brands/{brand_id}", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `PATCH` /api/v1/brands/{brand_id}

**Update Brand**

Update brand name, billing email, or docs custom domain. Brand admin only.

**Parameters**

- `brand_id` (path, integer, required)

**Request body**

```bash
curl -X PATCH 'https://app.opvs.ai/api/v1/brands/{brand_id}' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "brand_name": "string",
  "billing_email": "string",
  "docs_custom_domain": "string"
}'
```

```python
import httpx

resp = httpx.patch(
    "https://app.opvs.ai/api/v1/brands/{brand_id}",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"brand_name": "string", "billing_email": "string", "docs_custom_domain": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}", {
  method: "PATCH",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"brand_name": "string", "billing_email": "string", "docs_custom_domain": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"brand_name": "string", "billing_email": "string", "docs_custom_domain": "string"}`)
	req, _ := http.NewRequest("PATCH", "https://app.opvs.ai/api/v1/brands/{brand_id}", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/brands/{brand_id}/settings

**Get Brand Settings**

Get brand settings (voice, tone, logo).

**Parameters**

- `brand_id` (path, integer, required)
- `format` (query, any, optional) — Response format: yaml or md

```bash
curl -X GET 'https://app.opvs.ai/api/v1/brands/{brand_id}/settings' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/settings",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/settings", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/brands/{brand_id}/settings", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `PATCH` /api/v1/brands/{brand_id}/settings

**Update Brand Settings**

Update brand settings. Brand admin only.

**Parameters**

- `brand_id` (path, integer, required)

**Request body**

```bash
curl -X PATCH 'https://app.opvs.ai/api/v1/brands/{brand_id}/settings' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "brand_voice": "string",
  "brand_name_meaning": "string",
  "brand_tone": "string",
  "brand_promis": "string",
  "logo_big": "string"
}'
```

```python
import httpx

resp = httpx.patch(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/settings",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"brand_voice": "string", "brand_name_meaning": "string", "brand_tone": "string", "brand_promis": "string", "logo_big": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/settings", {
  method: "PATCH",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"brand_voice": "string", "brand_name_meaning": "string", "brand_tone": "string", "brand_promis": "string", "logo_big": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"brand_voice": "string", "brand_name_meaning": "string", "brand_tone": "string", "brand_promis": "string", "logo_big": "string"}`)
	req, _ := http.NewRequest("PATCH", "https://app.opvs.ai/api/v1/brands/{brand_id}/settings", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/brands/{brand_id}/info

**Get Brand Info**

Get brand information (address, tax).

**Parameters**

- `brand_id` (path, integer, required)
- `format` (query, any, optional) — Response format: yaml or md

```bash
curl -X GET 'https://app.opvs.ai/api/v1/brands/{brand_id}/info' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/info",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/info", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/brands/{brand_id}/info", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `PATCH` /api/v1/brands/{brand_id}/info

**Update Brand Info**

Update brand information. Brand admin only.

**Parameters**

- `brand_id` (path, integer, required)

**Request body**

```bash
curl -X PATCH 'https://app.opvs.ai/api/v1/brands/{brand_id}/info' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "website": "string",
  "street1": "string",
  "street2": "string",
  "postcode": "string",
  "city": "string",
  "state": "string",
  "country": "string",
  "tax_id": "string",
  "vat_id": "string"
}'
```

```python
import httpx

resp = httpx.patch(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/info",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"website": "string", "street1": "string", "street2": "string", "postcode": "string", "city": "string", "state": "string", "country": "string", "tax_id": "string", "vat_id": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/info", {
  method: "PATCH",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"website": "string", "street1": "string", "street2": "string", "postcode": "string", "city": "string", "state": "string", "country": "string", "tax_id": "string", "vat_id": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"website": "string", "street1": "string", "street2": "string", "postcode": "string", "city": "string", "state": "string", "country": "string", "tax_id": "string", "vat_id": "string"}`)
	req, _ := http.NewRequest("PATCH", "https://app.opvs.ai/api/v1/brands/{brand_id}/info", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/brands/{brand_id}/members

**List Brand Members**

List members of a brand.

**Parameters**

- `brand_id` (path, integer, required)
- `format` (query, any, optional) — Response format: yaml or md

```bash
curl -X GET 'https://app.opvs.ai/api/v1/brands/{brand_id}/members' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/members",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/members", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/brands/{brand_id}/members", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `PATCH` /api/v1/brands/{brand_id}/members/{user_id}

**Update Brand Member**

Update a member's role or position. Brand admin only.

**Parameters**

- `brand_id` (path, integer, required)
- `user_id` (path, integer, required)

**Request body**

```bash
curl -X PATCH 'https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "role": "string",
  "position": "string"
}'
```

```python
import httpx

resp = httpx.patch(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"role": "string", "position": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}", {
  method: "PATCH",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"role": "string", "position": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"role": "string", "position": "string"}`)
	req, _ := http.NewRequest("PATCH", "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `DELETE` /api/v1/brands/{brand_id}/members/{user_id}

**Remove Brand Member**

Remove a member from the brand. Brand admin only.

**Parameters**

- `brand_id` (path, integer, required)
- `user_id` (path, integer, required)

```bash
curl -X DELETE 'https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.delete(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}", {
  method: "DELETE",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `POST` /api/v1/brands/{brand_id}/members/{user_id}/photo

**Upload Member Photo**

Upload a picture for a member of this brand.

**Parameters**

- `brand_id` (path, integer, required)
- `user_id` (path, integer, required)

**Request body**

```bash
curl -X POST 'https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/photo' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "file": "string"
}'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/photo",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"file": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/photo", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"file": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"file": "string"}`)
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/photo", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `DELETE` /api/v1/brands/{brand_id}/members/{user_id}/photo

**Remove Member Photo**

Remove a picture from a member of this brand.

**Parameters**

- `brand_id` (path, integer, required)
- `user_id` (path, integer, required)

```bash
curl -X DELETE 'https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/photo' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.delete(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/photo",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/photo", {
  method: "DELETE",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/photo", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `POST` /api/v1/brands/{brand_id}/members/{user_id}/reset-password

**Reset Member Password**

Send the member the existing password-reset email.

**Parameters**

- `brand_id` (path, integer, required)
- `user_id` (path, integer, required)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/reset-password' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/reset-password",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/reset-password", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/reset-password", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `POST` /api/v1/brands/{brand_id}/members/{user_id}/set-password

**Set Member Password**

Set a password only for an ordinary person who belongs to this brand alone.

**Parameters**

- `brand_id` (path, integer, required)
- `user_id` (path, integer, required)

**Request body**

```bash
curl -X POST 'https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/set-password' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "password": "string",
  "send_email": false
}'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/set-password",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"password": "string", "send_email": false},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/set-password", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"password": "string", "send_email": false})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"password": "string", "send_email": false}`)
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/set-password", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/brands/{brand_id}/guests

**List Guests**

List outside people and every board/docs resource they can open.

**Parameters**

- `brand_id` (path, integer, required)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/brands/{brand_id}/guests' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/guests",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/guests", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/brands/{brand_id}/guests", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `POST` /api/v1/brands/{brand_id}/guests/{user_id}/make-member

**Make Guest Member**

Invite a guest; their existing grants remain until they accept.

**Parameters**

- `brand_id` (path, integer, required)
- `user_id` (path, integer, required)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/brands/{brand_id}/guests/{user_id}/make-member' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/guests/{user_id}/make-member",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/guests/{user_id}/make-member", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/brands/{brand_id}/guests/{user_id}/make-member", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `201` — Successful Response
- `422` — Validation Error

## `DELETE` /api/v1/brands/{brand_id}/guests/{user_id}

**Remove Guest**

Remove every board/docs grant without deleting authored content.

**Parameters**

- `brand_id` (path, integer, required)
- `user_id` (path, integer, required)

```bash
curl -X DELETE 'https://app.opvs.ai/api/v1/brands/{brand_id}/guests/{user_id}' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.delete(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/guests/{user_id}",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/guests/{user_id}", {
  method: "DELETE",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/brands/{brand_id}/guests/{user_id}", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `POST` /api/v1/brands/{brand_id}/images/upload

**Upload Brand Image**

Upload an image to R2 storage. Returns a CDN URL.

**Parameters**

- `brand_id` (path, integer, required)

**Request body**

```bash
curl -X POST 'https://app.opvs.ai/api/v1/brands/{brand_id}/images/upload' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "file": "string"
}'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/images/upload",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"file": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/images/upload", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"file": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"file": "string"}`)
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/brands/{brand_id}/images/upload", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/brands/{brand_id}/images

**List Brand Images**

List images uploaded for this brand, newest first.

**Parameters**

- `brand_id` (path, integer, required)
- `limit` (query, integer, optional)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/brands/{brand_id}/images' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/images",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/images", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/brands/{brand_id}/images", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `DELETE` /api/v1/brands/{brand_id}/images

**Delete Brand Image**

Delete one uploaded image, if nothing still references it.

**Parameters**

- `brand_id` (path, integer, required)
- `url` (query, string, required) — The url the upload returned, or the bare storage key.

```bash
curl -X DELETE 'https://app.opvs.ai/api/v1/brands/{brand_id}/images' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.delete(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/images",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/images", {
  method: "DELETE",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://app.opvs.ai/api/v1/brands/{brand_id}/images", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `POST` /api/v1/brands/{brand_id}/logo

**Upload Brand Logo**

Upload a brand logo to R2 and store the URL in brand_settings.logo_big.

**Parameters**

- `brand_id` (path, integer, required)

**Request body**

```bash
curl -X POST 'https://app.opvs.ai/api/v1/brands/{brand_id}/logo' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "file": "string"
}'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/logo",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"file": "string"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/logo", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"file": "string"})
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"file": "string"}`)
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/brands/{brand_id}/logo", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `GET` /api/v1/brands/{brand_id}/docs-domain

**Get Docs Domain**

Get custom domain configuration for this brand's public docs.

**Parameters**

- `brand_id` (path, integer, required)

```bash
curl -X GET 'https://app.opvs.ai/api/v1/brands/{brand_id}/docs-domain' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.get(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/docs-domain",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/docs-domain", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://app.opvs.ai/api/v1/brands/{brand_id}/docs-domain", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## `POST` /api/v1/brands/{brand_id}/docs-domain/verify

**Verify Docs Domain**

Trigger DNS verification for the brand's custom domain.

**Parameters**

- `brand_id` (path, integer, required)

```bash
curl -X POST 'https://app.opvs.ai/api/v1/brands/{brand_id}/docs-domain/verify' \
  -H 'Authorization: Bearer <token>'
```

```python
import httpx

resp = httpx.post(
    "https://app.opvs.ai/api/v1/brands/{brand_id}/docs-domain/verify",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
```

```javascript
const resp = await fetch("https://app.opvs.ai/api/v1/brands/{brand_id}/docs-domain/verify", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
```

```go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://app.opvs.ai/api/v1/brands/{brand_id}/docs-domain/verify", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}
```

**Responses**

- `200` — Successful Response
- `422` — Validation Error

## List Brands

`GET https://app.opvs.ai/api/v1/brands`

List all brands the current user belongs to.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Brand

`GET https://app.opvs.ai/api/v1/brands/{brand_id}`

Get brand details. Requires membership.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Update Brand

`PATCH https://app.opvs.ai/api/v1/brands/{brand_id}`

Update brand name, billing email, or docs custom domain. Brand admin only.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Brand Settings

`GET https://app.opvs.ai/api/v1/brands/{brand_id}/settings`

Get brand settings (voice, tone, logo).

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Update Brand Settings

`PATCH https://app.opvs.ai/api/v1/brands/{brand_id}/settings`

Update brand settings. Brand admin only.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Brand Info

`GET https://app.opvs.ai/api/v1/brands/{brand_id}/info`

Get brand information (address, tax).

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Update Brand Info

`PATCH https://app.opvs.ai/api/v1/brands/{brand_id}/info`

Update brand information. Brand admin only.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## List Brand Members

`GET https://app.opvs.ai/api/v1/brands/{brand_id}/members`

List members of a brand.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Update Brand Member

`PATCH https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}`

Update a member's role or position. Brand admin only.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Remove Brand Member

`DELETE https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}`

Remove a member from the brand. Brand admin only.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Upload Member Photo

`POST https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/photo`

Upload a picture for a member of this brand.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Remove Member Photo

`DELETE https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/photo`

Remove a picture from a member of this brand.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Reset Member Password

`POST https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/reset-password`

Send the member the existing password-reset email.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Set Member Password

`POST https://app.opvs.ai/api/v1/brands/{brand_id}/members/{user_id}/set-password`

Set a password only for an ordinary person who belongs to this brand alone.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## List Guests

`GET https://app.opvs.ai/api/v1/brands/{brand_id}/guests`

List outside people and every board/docs resource they can open.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Make Guest Member

`POST https://app.opvs.ai/api/v1/brands/{brand_id}/guests/{user_id}/make-member`

Invite a guest; their existing grants remain until they accept.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Remove Guest

`DELETE https://app.opvs.ai/api/v1/brands/{brand_id}/guests/{user_id}`

Remove every board/docs grant without deleting authored content.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Upload Brand Image

`POST https://app.opvs.ai/api/v1/brands/{brand_id}/images/upload`

Upload an image to R2 storage. Returns a CDN URL.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## List Brand Images

`GET https://app.opvs.ai/api/v1/brands/{brand_id}/images`

List images uploaded for this brand, newest first.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Delete Brand Image

`DELETE https://app.opvs.ai/api/v1/brands/{brand_id}/images`

Delete one uploaded image, if nothing still references it.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Upload Brand Logo

`POST https://app.opvs.ai/api/v1/brands/{brand_id}/logo`

Upload a brand logo to R2 and store the URL in brand_settings.logo_big.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Get Docs Domain

`GET https://app.opvs.ai/api/v1/brands/{brand_id}/docs-domain`

Get custom domain configuration for this brand's public docs.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |

## Verify Docs Domain

`POST https://app.opvs.ai/api/v1/brands/{brand_id}/docs-domain/verify`

Trigger DNS verification for the brand's custom domain.

| Code | When | What to do |
| --- | --- | --- |
| 422 | Validation Error |  |
