Appearance
reseller-settings
6 endpoints.
GET /api/v1/reseller-settings/profile
Get Profile
Scoped per-reseller (_profile_key): once a reseller saves their own profile it's authoritative for THEM going forward, never affecting (or affected by) another reseller's saved profile. Before that first save, pre-populate from the signed-in reseller's own tc AccCustomer record rather than showing a blank form — falls back to the bare model default (e.g. "Cloud Tools") for superusers / logins with no linked reseller.
200 — Successful Response
json
{
"properties": {
"company_name": {
"type": "string",
"maxLength": 120,
"title": "Company Name",
"default": "Cloud Tools"
},
"contact_name": {
"type": "string",
"maxLength": 120,
"title": "Contact Name",
"default": ""
},
"contact_email": {
"type": "string",
"maxLength": 200,
"title": "Contact Email",
"default": ""
},
"contact_phone": {
"type": "string",
"maxLength": 40,
"title": "Contact Phone",
"default": ""
},
"address": {
"type": "string",
"maxLength": 500,
"title": "Address",
"default": ""
},
"vat_number": {
"type": "string",
"maxLength": 60,
"title": "Vat Number",
"default": ""
},
"registration_number": {
"type": "string",
"maxLength": 60,
"title": "Registration Number",
"default": ""
},
"website": {
"type": "string",
"maxLength": 200,
"title": "Website",
"default": ""
},
"account_number": {
"type": "string",
"maxLength": 64,
"title": "Account Number",
"default": ""
}
},
"type": "object",
"title": "ResellerProfile",
"description": "Company profile of the reseller operating this portal."
}PUT /api/v1/reseller-settings/profile
Update Profile
Request body
json
{
"properties": {
"company_name": {
"type": "string",
"maxLength": 120,
"title": "Company Name",
"default": "Cloud Tools"
},
"contact_name": {
"type": "string",
"maxLength": 120,
"title": "Contact Name",
"default": ""
},
"contact_email": {
"type": "string",
"maxLength": 200,
"title": "Contact Email",
"default": ""
},
"contact_phone": {
"type": "string",
"maxLength": 40,
"title": "Contact Phone",
"default": ""
},
"address": {
"type": "string",
"maxLength": 500,
"title": "Address",
"default": ""
},
"vat_number": {
"type": "string",
"maxLength": 60,
"title": "Vat Number",
"default": ""
},
"registration_number": {
"type": "string",
"maxLength": 60,
"title": "Registration Number",
"default": ""
},
"website": {
"type": "string",
"maxLength": 200,
"title": "Website",
"default": ""
},
"account_number": {
"type": "string",
"maxLength": 64,
"title": "Account Number",
"default": ""
}
},
"type": "object",
"title": "ResellerProfile",
"description": "Company profile of the reseller operating this portal."
}200 — Successful Response
json
{
"properties": {
"company_name": {
"type": "string",
"maxLength": 120,
"title": "Company Name",
"default": "Cloud Tools"
},
"contact_name": {
"type": "string",
"maxLength": 120,
"title": "Contact Name",
"default": ""
},
"contact_email": {
"type": "string",
"maxLength": 200,
"title": "Contact Email",
"default": ""
},
"contact_phone": {
"type": "string",
"maxLength": 40,
"title": "Contact Phone",
"default": ""
},
"address": {
"type": "string",
"maxLength": 500,
"title": "Address",
"default": ""
},
"vat_number": {
"type": "string",
"maxLength": 60,
"title": "Vat Number",
"default": ""
},
"registration_number": {
"type": "string",
"maxLength": 60,
"title": "Registration Number",
"default": ""
},
"website": {
"type": "string",
"maxLength": 200,
"title": "Website",
"default": ""
},
"account_number": {
"type": "string",
"maxLength": 64,
"title": "Account Number",
"default": ""
}
},
"type": "object",
"title": "ResellerProfile",
"description": "Company profile of the reseller operating this portal."
}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}GET /api/v1/reseller-settings/branding
Get Branding
200 — Successful Response
json
{
"properties": {
"logo_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Logo Url"
},
"logo_dark_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Logo Dark Url"
},
"favicon_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Favicon Url"
},
"primary_color": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"title": "Primary Color"
},
"primary_foreground": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"title": "Primary Foreground"
}
},
"type": "object",
"title": "ResellerBranding",
"description": "Visual identity of the reseller operating this portal. Same URL shapes\nas Branding.logo_url (http(s) or an inline data: URL)."
}PUT /api/v1/reseller-settings/branding
Update Branding
Request body
json
{
"properties": {
"logo_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Logo Url"
},
"logo_dark_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Logo Dark Url"
},
"favicon_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Favicon Url"
},
"primary_color": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"title": "Primary Color"
},
"primary_foreground": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"title": "Primary Foreground"
}
},
"type": "object",
"title": "ResellerBranding",
"description": "Visual identity of the reseller operating this portal. Same URL shapes\nas Branding.logo_url (http(s) or an inline data: URL)."
}200 — Successful Response
json
{
"properties": {
"logo_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Logo Url"
},
"logo_dark_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Logo Dark Url"
},
"favicon_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Favicon Url"
},
"primary_color": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"title": "Primary Color"
},
"primary_foreground": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"title": "Primary Foreground"
}
},
"type": "object",
"title": "ResellerBranding",
"description": "Visual identity of the reseller operating this portal. Same URL shapes\nas Branding.logo_url (http(s) or an inline data: URL)."
}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}POST /api/v1/reseller-settings/users
Create Reseller User
Create a sub-account under the SIGNED-IN reseller: a real portal login (password set here directly, no invite email — the reseller is vouching for this person) plus an AccCustomer row on the books site (tc) with reseller_id pointing at the signed-in reseller's own account (customer_group="Reseller User" — the 2026-07-28 reseller_users -> acc_customer migration; end-users are no longer a separate table). Reseller-only (not superuser — there's no "logged in reseller" for a platform admin to create under).
Request body
json
{
"properties": {
"name": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"title": "Name"
},
"email": {
"type": "string",
"format": "email",
"title": "Email"
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"title": "Phone"
},
"password": {
"type": "string",
"maxLength": 200,
"minLength": 8,
"title": "Password"
}
},
"type": "object",
"required": [
"name",
"email",
"password"
],
"title": "NewResellerUser",
"description": "A reseller's own sub-account, created directly with a password (not the\ninvite-email flow the tc->portal sync uses for direct customers) — the\nreseller is vouching for this person themselves, so it takes effect\nimmediately rather than waiting on an activation email."
}201 — Successful Response
json
{
"additionalProperties": true,
"type": "object",
"title": "Response Create Reseller User Api V1 Reseller Settings Users Post"
}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}PUT /api/v1/reseller-settings/users/{ru_id}
Update Reseller User
Edit a sub-account under the SIGNED-IN reseller (name/email/phone/status). The row lives on tc as an AccCustomer (see create_reseller_user) — scoped so a reseller can only ever touch a row whose reseller_id matches their OWN account's integer id, never another reseller's. Doesn't touch the linked portal login (if any) — see UpdateResellerUser.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
ru_id | path | yes | string |
Request body
json
{
"properties": {
"name": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"title": "Name"
},
"email": {
"type": "string",
"format": "email",
"title": "Email"
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"title": "Phone"
},
"status": {
"type": "string",
"maxLength": 32,
"title": "Status",
"default": "active"
}
},
"type": "object",
"required": [
"name",
"email"
],
"title": "UpdateResellerUser",
"description": "Editing an existing sub-account under the signed-in reseller. Only the\nResellerUser record on tc is touched — the linked portal login (if any,\nsee ResellerUser.portal_tenant_id) is out of scope here."
}200 — Successful Response
json
{
"type": "object",
"additionalProperties": true,
"title": "Response Update Reseller User Api V1 Reseller Settings Users Ru Id Put"
}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}