## PATCH /api/v2/me

**Update current account profile**

Update mutable profile fields on the authenticated account and return the refreshed `AccountMe` snapshot. Send only the documented public v2 fields; do not send `accountId`, internal field names, email, password, MFA, BankID-only login, or BankID personnummer values here. Email and password changes use dedicated `/api/v2/me/actions/...` routes. Delegated-access sessions and admin sessions that are not impersonating a client cannot mutate profile details through this endpoint.

### Related Endpoints

- `GET /api/v2/me`: Get current account profile
- `GET /api/v2/me/preferences`: Get account preferences
- `PATCH /api/v2/me/preferences`: Update account preferences

### Headers

- `Accept`: application/json
- `Authorization`: Bearer YOUR_API_KEY
- Required API scope: `write:account`
- `Content-Type`: application/json

### Request Body

- `firstName` (string, optional) Example: `Anna`
- `lastName` (string, optional) Example: `Svensson`
- `companyName` (string,null, optional) Example: `Example AB`
- `countryCode` (string, optional) Example: `SE`
- `phoneNumber` (string, optional) Example: `+46700000000`
- `languageCode` (string, optional): Preferred language as an ISO-style language code. Example: `sv`
  Allowed values: sv, en, no, da, fi, de
- `vatNumber` (string,null, optional) Example: `SE559999999901`
- `invoiceReference` (string,null, optional) Example: `Cost center 42`
- `accountType` (string, optional) Example: `organisation`
  Allowed values: private, organisation
- `registrationIdentifier` (object | null, optional): Organisation number or personal identifier. Send null to clear it.
- `registrationIdentifier.value` (string, required) Example: `559290-1325`
- `registrationIdentifier.countryCode` (string,null, optional) Example: `SE`
- `address` (object, optional)
- `address.street` (string,null, optional) Example: `Examplegatan 1`
- `address.city` (string,null, optional) Example: `Stockholm`
- `address.postalCode` (string,null, optional) Example: `12345`
- `address.state` (string,null, optional) Example: `null`

### Request Examples

#### Complete profile fields needed for domain orders

```bash
curl -X PATCH "https://cloud.hostup.se/api/v2/me" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "+46700000000",
    "registrationIdentifier": {
      "value": "850507-3412",
      "countryCode": "SE"
    }
  }'
```

```json
{
  "phoneNumber": "+46700000000",
  "registrationIdentifier": {
    "value": "850507-3412",
    "countryCode": "SE"
  }
}
```

#### Update organisation billing profile

```bash
curl -X PATCH "https://cloud.hostup.se/api/v2/me" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "accountType": "organisation",
    "companyName": "Example AB",
    "vatNumber": "SE559999999901",
    "invoiceReference": "Cost center 42",
    "address": {
      "street": "Examplegatan 1",
      "city": "Stockholm",
      "postalCode": "12345",
      "state": null
    }
  }'
```

```json
{
  "accountType": "organisation",
  "companyName": "Example AB",
  "vatNumber": "SE559999999901",
  "invoiceReference": "Cost center 42",
  "address": {
    "street": "Examplegatan 1",
    "city": "Stockholm",
    "postalCode": "12345",
    "state": null
  }
}
```

#### Change account language

```bash
curl -X PATCH "https://cloud.hostup.se/api/v2/me" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "languageCode": "sv"
  }'
```

```json
{
  "languageCode": "sv"
}
```

### Response Schema

- `id` (string, optional): Public client/account ID. Example: `client_01hxa3b4c5d6e7f8g9h0j1k2m3`
- `name` (string,null, optional): Best display name for the account. Example: `Anna Svensson`
- `email` (string,null, optional) Example: `user@example.com`
- `firstName` (string,null, optional) Example: `Anna`
- `lastName` (string,null, optional) Example: `Svensson`
- `companyName` (string,null, optional) Example: `null`
- `registrationIdentifier` (null, optional): Normalized organisation number or personal identifier when present.
- `countryCode` (string,null, optional) Example: `SE`
- `phoneNumber` (string,null, optional): Normalized E.164-style phone number when present. Example: `+46700000000`
- `languageCode` (string,null, optional) Example: `sv`
- `currencyCode` (string,null, optional) Example: `SEK`
- `accountType` (string, optional) Example: `private`
  Allowed values: private, organisation
- `vatNumber` (string,null, optional) Example: `null`
- `invoiceReference` (string,null, optional): Custom invoice reference line shown on future invoices. Example: `null`
- `profileRequirements` (object | null, optional): Profile fields the account must complete for active services or future order flows.
- `profileRequirements.fields` (object, required)
- `profileRequirements.fields.phoneNumber` (object, required): Server-derived account-profile requirement. Consumers should render this decision instead of re-deriving registry or product rules locally.
- `profileRequirements.fields.phoneNumber.required` (boolean, required) Example: `true`
- `profileRequirements.fields.phoneNumber.fulfilled` (boolean, required) Example: `false`
- `profileRequirements.fields.phoneNumber.reason` (string,null, required) Example: `A phone number is required because your account has active domains.`
- `profileRequirements.fields.phoneNumber.source` (string,null, required) Example: `active_domains`
  Allowed values: active_domains, active_se_nu_domains, 
- `profileRequirements.fields.phoneNumber.domainCount` (integer, required) Example: `2`
- `profileRequirements.fields.registrationIdentifier` (object, required): Server-derived account-profile requirement. Consumers should render this decision instead of re-deriving registry or product rules locally.
- `profileRequirements.fields.registrationIdentifier.required` (boolean, required) Example: `true`
- `profileRequirements.fields.registrationIdentifier.fulfilled` (boolean, required) Example: `false`
- `profileRequirements.fields.registrationIdentifier.reason` (string,null, required) Example: `A phone number is required because your account has active domains.`
- `profileRequirements.fields.registrationIdentifier.source` (string,null, required) Example: `active_domains`
  Allowed values: active_domains, active_se_nu_domains, 
- `profileRequirements.fields.registrationIdentifier.domainCount` (integer, required) Example: `2`
- `profileRequirements.missingFields` (array<string>, required) Example: `["phoneNumber"]`
- `address` (object, optional)
- `address.street` (string,null, required) Example: `Examplegatan 1`
- `address.city` (string,null, required) Example: `Stockholm`
- `address.postalCode` (string,null, required) Example: `12345`
- `address.state` (string,null, required) Example: `null`
- `verified` (boolean, optional): Whether the account identity has been verified. Example: `true`
- `adminId` (string,null, optional): Admin ID only when an admin is impersonating a client. Example: `null`
- `isAdmin` (boolean, optional) Example: `false`
- `isContact` (boolean, optional) Example: `false`
- `canPlaceOrders` (boolean, optional) Example: `true`
- `impersonating` (boolean, optional) Example: `false`
- `authType` (string, optional) Example: `session`
  Allowed values: session, api-key, admin, bankid-selection, billing-sso
- `shouldMigrateMFA` (boolean, optional) Example: `false`
- `bankidUserName` (string,null, optional) Example: `Anna Svensson`
- `scopes` (array<string>, optional) Example: `["read:account","write:account"]`
- `canViewInvoices` (boolean, optional) Example: `true`
- `canViewTickets` (boolean, optional) Example: `true`
- `canAccessCdn` (boolean, optional) Example: `true`
- `canRequestEpp` (boolean, optional) Example: `true`
- `adminUsername` (string,null, optional) Example: `null`
- `adminRoles` (array<string>, optional) Example: `[]`
- `adminLanguage` (string,null, optional) Example: `null`
- `parentClientId` (string,null, optional) Example: `null`
- `parentEmail` (string,null, optional) Example: `null`
- `isBillingSso` (boolean, optional) Example: `false`
- `isDelegatedAccess` (boolean, optional) Example: `false`
- `hasDelegatedGrants` (boolean, optional) Example: `false`
- `hasOwnedAccounts` (boolean, optional) Example: `false`
- `delegatedLabel` (string,null, optional) Example: `null`
- `delegatedGrantId` (string,null, optional) Example: `null`
- `uiBanners` (object | null, optional): Precomputed dashboard banner decisions, or null when not applicable to the caller.
- `uiBanners.eurCurrency` (object, required)
- `uiBanners.eurCurrency.show` (boolean, required) Example: `false`
- `uiBanners.eurCurrency.reason` (string,null, required) Example: `User country is SE - banner suppressed.`
- `uiBanners.pendingOrder` (object, required)
- `uiBanners.pendingOrder.show` (boolean, required) Example: `false`
- `uiBanners.pendingOrder.reason` (string,null, required) Example: `BankID verification already completed.`
- `uiBanners.pendingOrder.order` (object,null, required) Example: `null`
- `emailChangeState` (object, optional)
- `emailChangeState.status` (string, required) Example: `none`
  Allowed values: none, pending, verified
- `emailChangeState.pendingEmail` (string,null, required) Example: `null`
- `emailChangeState.expiresAt` (string,null, required) Example: `null`
- `actions` (object, optional)
- `actions.canChangeEmail` (object, required)
- `actions.canChangeEmail.allowed` (boolean, required) Example: `true`
- `actions.canChangeEmail.reason` (string,null, required) Example: `null`
- `actions.canChangeEmail.code` (string,null, optional): Machine-readable reason code when an action is blocked. Example: `pending_order`
- `actions.canChangePassword` (object, required)
- `actions.canChangePassword.allowed` (boolean, required) Example: `true`
- `actions.canChangePassword.reason` (string,null, required) Example: `null`
- `actions.canChangePassword.code` (string,null, optional): Machine-readable reason code when an action is blocked. Example: `pending_order`
- `actions.canSetupBankID` (object, required)
- `actions.canSetupBankID.allowed` (boolean, required) Example: `true`
- `actions.canSetupBankID.reason` (string,null, required) Example: `null`
- `actions.canSetupBankID.code` (string,null, optional): Machine-readable reason code when an action is blocked. Example: `pending_order`

### Responses

#### 200 - Profile updated. The response is the refreshed current-account snapshot.
```json
{
  "id": "client_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "name": "Anna Svensson",
  "email": "user@example.com",
  "firstName": "Anna",
  "lastName": "Svensson",
  "companyName": "Example AB",
  "registrationIdentifier": {
    "value": "850507-3412",
    "countryCode": "SE",
    "type": "personal_identifier"
  },
  "countryCode": "SE",
  "phoneNumber": "+46700000000",
  "languageCode": "sv",
  "currencyCode": "SEK",
  "accountType": "organisation",
  "vatNumber": null,
  "invoiceReference": "websites",
  "profileRequirements": {
    "fields": {
      "phoneNumber": {
        "required": true,
        "fulfilled": true,
        "reason": "A phone number is required because your account has active domains.",
        "source": "active_domains",
        "domainCount": 2
      },
      "registrationIdentifier": {
        "required": true,
        "fulfilled": true,
        "reason": "A personal identity number is required because your account has active .se or .nu domains.",
        "source": "active_se_nu_domains",
        "domainCount": 1
      }
    },
    "missingFields": []
  },
  "address": {
    "street": "Examplegatan 1",
    "city": "Stockholm",
    "postalCode": "12345",
    "state": "Stockholm County"
  },
  "verified": true,
  "adminId": null,
  "isAdmin": false,
  "isContact": false,
  "canPlaceOrders": true,
  "impersonating": false,
  "authType": "session",
  "shouldMigrateMFA": false,
  "bankidUserName": "Anna Svensson",
  "scopes": [
    "read:account",
    "write:account",
    "read:billing",
    "read:support"
  ],
  "canViewInvoices": true,
  "canViewTickets": true,
  "canAccessCdn": true,
  "canRequestEpp": true,
  "adminUsername": null,
  "adminRoles": [],
  "adminLanguage": null,
  "parentClientId": null,
  "parentEmail": null,
  "isBillingSso": false,
  "isDelegatedAccess": false,
  "hasDelegatedGrants": false,
  "hasOwnedAccounts": false,
  "delegatedLabel": null,
  "delegatedGrantId": null,
  "uiBanners": {
    "eurCurrency": {
      "show": false,
      "reason": "User country is SE - banner suppressed."
    },
    "pendingOrder": {
      "show": false,
      "reason": "BankID verification already completed.",
      "order": null
    }
  },
  "emailChangeState": {
    "status": "none",
    "pendingEmail": null,
    "expiresAt": null
  },
  "actions": {
    "canChangeEmail": {
      "allowed": true,
      "reason": null
    },
    "canChangePassword": {
      "allowed": true,
      "reason": null
    },
    "canSetupBankID": {
      "allowed": true,
      "reason": null
    }
  }
}
```

#### 400 - The request body failed validation.
```json
{
  "type": "https://developer.hostup.se/errors/invalid_request",
  "title": "Validation failed",
  "status": 400,
  "detail": "The request body failed validation.",
  "code": "invalid_request",
  "instance": "/api/v2/orders",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z",
  "errors": [
    {
      "pointer": "/items/0/eppCode",
      "detail": "`eppCode` is required for this transfer.",
      "code": "missing_required"
    }
  ],
  "extensions": {}
}
```

#### 401 - Authentication is required.
```json
{
  "type": "https://developer.hostup.se/errors/invalid_request",
  "title": "Validation failed",
  "status": 400,
  "detail": "The request body failed validation.",
  "code": "invalid_request",
  "instance": "/api/v2/orders",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z",
  "errors": [
    {
      "pointer": "/items/0/eppCode",
      "detail": "`eppCode` is required for this transfer.",
      "code": "missing_required"
    }
  ],
  "extensions": {}
}
```

#### 403 - The current session is not allowed to update this account profile.
```json
{
  "type": "https://developer.hostup.se/errors/invalid_request",
  "title": "Validation failed",
  "status": 400,
  "detail": "The request body failed validation.",
  "code": "invalid_request",
  "instance": "/api/v2/orders",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z",
  "errors": [
    {
      "pointer": "/items/0/eppCode",
      "detail": "`eppCode` is required for this transfer.",
      "code": "missing_required"
    }
  ],
  "extensions": {}
}
```

#### 404 - Not found. The resource does not exist or is not owned by the caller.
```json
{
  "type": "https://developer.hostup.se/errors/not_found",
  "title": "Not found",
  "status": 404,
  "detail": "The requested resource could not be found.",
  "code": "not_found",
  "instance": "/api/v2/resource",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z"
}
```

#### 429 - Rate limited. Retry after the limit resets. 429 responses include `Retry-After` seconds plus `X-RateLimit-*` headers.
```json
{
  "type": "https://developer.hostup.se/errors/rate_limit_exceeded",
  "title": "Too many requests",
  "status": 429,
  "detail": "Too many requests. Retry after the limit resets.",
  "code": "rate_limit_exceeded",
  "instance": "/api/v2/resource",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z"
}
```

#### 500 - Internal error. Retry later or contact support if the issue persists.
```json
{
  "type": "https://developer.hostup.se/errors/internal_error",
  "title": "Internal server error",
  "status": 500,
  "detail": "An unexpected error occurred. Retry later or contact support if the issue persists.",
  "code": "internal_error",
  "instance": "/api/v2/resource",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z"
}
```
