> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://fyno.io/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://fyno.io/docs/_mcp/server.

# Update user profile

PUT https://api.fyno.io/v1/{WSID}/{version}/profiles/{distinct_id}
Content-Type: application/json

This API enables you to update an existing user profile. You can modify any supported profile attribute, including the user's `distinct_id` (if specified).

**Note:**

* Fields included in the request overwrite the existing values.
* Fields omitted from the request remain unchanged.
* If you change any value within the `channel` object, the entire `channel` data for that request is replaced (not merged), except for `inapp`, `push`, and `webpush`, whose tokens are appended as new device registrations.

You only need to include the fields that require changes in the request body:

```json
{
  "distinct_id": "user_12345",
  "name": "John Doe",
  "timezone": "Asia/Kolkata",
  "status": 1,
  "channel": {
    "email": "john@example.com",
    "sms": "+48XXXXXXX10",
    "whatsapp": "+41XXXXXXX10",
    "push": [
      {
        "token": "device_token",
        "integration_id": "push_integration",
        "status": 1
      }
    ]
  }
}
```

The `channel` object can contain one or more of the following channels: `email`, `sms`, `rcs`, `whatsapp`, `voice`, `slack`, `discord`, `teams`, `inapp`, `push`, and `webpush`.

The `inapp` and `push` arrays each contain device registrations with a required `token` and `status` (`1`=Active, `0`=Inactive), and an optional `integration_id`.

The `webpush` array contains Web Push subscriptions. The `token` field for a `webpush` entry may be either a non-empty string or a Push Subscription object containing `endpoint` (required), `expirationTime` (optional, nullable), and `keys` with `p256dh` and `auth` (both required when `token` is an object).

Reference: https://fyno.io/docs/api-reference/update-user-profile

## Authentication

- `Authorization` header (bearer token, required) — Enter your API Key. If you don't have it already, you can create one from the API Keys page within your Fyno account

## Request

### Path parameters

- `WSID` (string, required) — Enter your workspace ID. You can obtain this value from the API Keys page within your Fyno account.
- `version` (string, required) — Specify the version for which you would like to manage the user profile. Supported values are `live` and `tested`.
- `distinct_id` (string, required) — Enter the current distinct ID that uniquely identifies the user profile you want to update.

### Body (application/json)

This endpoint expects a profiles_distinct_id_body.

- `channel` (WSIDversionprofilesdistinct_id_channel, optional) — (Optional) If you do not wish to change any channel values, remove this key from the payload. Note: If you change any value in the `channel` key, the entire channel data is replaced.
- `distinct_id` (string, optional) — (Optional) Enter the new distinct ID that you wish to use to identify the user. If provided, it replaces the existing distinct ID. If you do not wish to change this value, remove this key from the payload.
- `name` (string, optional) — (Optional) Enter the new full name of the user. If you do not wish to change this value, remove this key from the payload.
- `status` (enum, optional) — (Optional) Enter 1 to change the user's status to active so that the user can receive notifications. Enter 0 to change the user's status to inactive so that the user does not receive any notification. If you do not wish to change this value, remove this key from the payload. If null, the default value is 1.
  - Allowed values: `1`, `0`
- `timezone` (string, optional) — (Optional) Enter the new timezone of the user. Must be a valid IANA timezone. For a list of possible values, please click here.

## Response

### 200

Profile updated successfully

- `_message` (string, required)
- `status` (string, required)

## Errors

### 400 Bad Request Error

Distinct ID does not exist

- `_message` (string, required)
- `status` (string, required)

### 401 Unauthorized Error

API Key or Workspace ID is invalid. User is unauthorised.

- `_message` (string, required)
- `status` (string, required)

## Types

### WSIDversionprofilesdistinct_id_channel

(Optional) If you do not wish to change any channel values, remove this key from the payload. Note: If you change any value in the `channel` key, the entire channel data is replaced.

- `discord` (string, optional) — Enter the new discord ID of the user.
- `email` (string, optional) — Enter the new email address of the user.
- `inapp` (list of WSIDversionprofilesdistinct_id_channel_inapp, optional)
- `push` (list of WSIDversionprofilesdistinct_id_channel_push, optional)
- `slack` (string, optional) — Enter the new channel ID, user ID, or email address of the user.
- `sms` (string, optional) — Enter the new mobile number of the user. The number must start with the country code (preferably in E.164 format). For example: +49XXXXXXXXX.
- `teams` (string, optional) — Enter the new channel name. For teams, we currently support sending to one channel only. To send to multiple channels, do get in touch and we can share a workaround.
- `voice` (string, optional) — Enter the new mobile number of the user. The number must start with the country code (preferably in E.164 format). For example: +49XXXXXXXXX.
- `whatsapp` (string, optional) — Enter the new WhatsApp mobile number of the user. The number must start with the country code (preferably in E.164 format). For example: +49XXXXXXXXX

### WSIDversionprofilesdistinct_id_channel_inapp

- `token` (string, required) — Enter the new distinct ID or the generated token of the user.
- `integration_id` (string, optional) — (Optional) Enter the integration ID that was used to generate the above token. This is helpful in identifying which integration to use when an account has multiple InApp integrations. If this value is null, then the above token is used for all InApp integrations. The integration ID can be obtained from Fyno's integrations page.
- `status` (enum, optional) — (Optional) Enter 1 to specify that this token must be active and should receive notifications. Enter 0 to specify that this token must be inactive and should not receive any notifications. If null, the default value is 1.
  - Allowed values: `1`, `0`

### WSIDversionprofilesdistinct_id_channel_push

- `token` (string, required) — Enter the new push token of the user. If you use OneSignal, you must add the following prefix to the token: For OneSignal playerId: `onesignal_player_id:`\<enter\_playerid> For OneSignal externalId: `onesignal_external_id:`\<enter\_externalid>
- `integration_id` (string, optional) — (Optional) Enter the integration ID that was used to generate the above token. This is helpful in identifying which integration to use when an account has multiple push integrations. If this value is null, then the above token is used for all push integrations. The integration ID can be obtained from Fyno's integrations page.
- `status` (enum, optional) — (Optional) Enter 1 to specify that this token must be active and should receive notifications. Enter 0 to specify that this token must be inactive and should not receive any notifications. If null, the default value is 1.
  - Allowed values: `1`, `0`

## Examples

**Request**

```json
{
  "channel": {
    "email": "john@example.com",
    "push": [
      {
        "token": "device_token",
        "integration_id": "push_integration",
        "status": 1
      }
    ],
    "sms": "+4XXXXXXXXXXX",
    "whatsapp": "+4XXXXXXXXXXX"
  },
  "distinct_id": "user_12345",
  "name": "John Doe",
  "status": 1,
  "timezone": "Asia/Kolkata"
}
```

**Response**

```json
{
  "_message": "1 Record(s) updated successfully",
  "status": "ok"
}
```

**SDK Code**

```python Manage User Profiles_updateUserProfile_example
import requests

url = "https://api.fyno.io/v1/FYXXXXXXXX/version/profiles/XXXXXXXX"

payload = {
    "channel": {
        "email": "john@example.com",
        "push": [
            {
                "token": "device_token",
                "integration_id": "push_integration",
                "status": 1
            }
        ],
        "sms": "+4XXXXXXXXXXX",
        "whatsapp": "+4XXXXXXXXXXX"
    },
    "distinct_id": "user_12345",
    "name": "John Doe",
    "status": 1,
    "timezone": "Asia/Kolkata"
}
headers = {
    "Authorization": "Bearer <apiKey>",
    "Content-Type": "application/json"
}

response = requests.put(url, json=payload, headers=headers)

print(response.json())
```

```javascript Manage User Profiles_updateUserProfile_example
const url = 'https://api.fyno.io/v1/FYXXXXXXXX/version/profiles/XXXXXXXX';
const options = {
  method: 'PUT',
  headers: {Authorization: 'Bearer <apiKey>', 'Content-Type': 'application/json'},
  body: '{"channel":{"email":"john@example.com","push":[{"token":"device_token","integration_id":"push_integration","status":1}],"sms":"+4XXXXXXXXXXX","whatsapp":"+4XXXXXXXXXXX"},"distinct_id":"user_12345","name":"John Doe","status":1,"timezone":"Asia/Kolkata"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Manage User Profiles_updateUserProfile_example
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.fyno.io/v1/FYXXXXXXXX/version/profiles/XXXXXXXX"

	payload := strings.NewReader("{\n  \"channel\": {\n    \"email\": \"john@example.com\",\n    \"push\": [\n      {\n        \"token\": \"device_token\",\n        \"integration_id\": \"push_integration\",\n        \"status\": 1\n      }\n    ],\n    \"sms\": \"+4XXXXXXXXXXX\",\n    \"whatsapp\": \"+4XXXXXXXXXXX\"\n  },\n  \"distinct_id\": \"user_12345\",\n  \"name\": \"John Doe\",\n  \"status\": 1,\n  \"timezone\": \"Asia/Kolkata\"\n}")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("Authorization", "Bearer <apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Manage User Profiles_updateUserProfile_example
require 'uri'
require 'net/http'

url = URI("https://api.fyno.io/v1/FYXXXXXXXX/version/profiles/XXXXXXXX")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"channel\": {\n    \"email\": \"john@example.com\",\n    \"push\": [\n      {\n        \"token\": \"device_token\",\n        \"integration_id\": \"push_integration\",\n        \"status\": 1\n      }\n    ],\n    \"sms\": \"+4XXXXXXXXXXX\",\n    \"whatsapp\": \"+4XXXXXXXXXXX\"\n  },\n  \"distinct_id\": \"user_12345\",\n  \"name\": \"John Doe\",\n  \"status\": 1,\n  \"timezone\": \"Asia/Kolkata\"\n}"

response = http.request(request)
puts response.read_body
```

```java Manage User Profiles_updateUserProfile_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.put("https://api.fyno.io/v1/FYXXXXXXXX/version/profiles/XXXXXXXX")
  .header("Authorization", "Bearer <apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"channel\": {\n    \"email\": \"john@example.com\",\n    \"push\": [\n      {\n        \"token\": \"device_token\",\n        \"integration_id\": \"push_integration\",\n        \"status\": 1\n      }\n    ],\n    \"sms\": \"+4XXXXXXXXXXX\",\n    \"whatsapp\": \"+4XXXXXXXXXXX\"\n  },\n  \"distinct_id\": \"user_12345\",\n  \"name\": \"John Doe\",\n  \"status\": 1,\n  \"timezone\": \"Asia/Kolkata\"\n}")
  .asString();
```

```php Manage User Profiles_updateUserProfile_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PUT', 'https://api.fyno.io/v1/FYXXXXXXXX/version/profiles/XXXXXXXX', [
  'body' => '{
  "channel": {
    "email": "john@example.com",
    "push": [
      {
        "token": "device_token",
        "integration_id": "push_integration",
        "status": 1
      }
    ],
    "sms": "+4XXXXXXXXXXX",
    "whatsapp": "+4XXXXXXXXXXX"
  },
  "distinct_id": "user_12345",
  "name": "John Doe",
  "status": 1,
  "timezone": "Asia/Kolkata"
}',
  'headers' => [
    'Authorization' => 'Bearer <apiKey>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Manage User Profiles_updateUserProfile_example
using RestSharp;

var client = new RestClient("https://api.fyno.io/v1/FYXXXXXXXX/version/profiles/XXXXXXXX");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"channel\": {\n    \"email\": \"john@example.com\",\n    \"push\": [\n      {\n        \"token\": \"device_token\",\n        \"integration_id\": \"push_integration\",\n        \"status\": 1\n      }\n    ],\n    \"sms\": \"+4XXXXXXXXXXX\",\n    \"whatsapp\": \"+4XXXXXXXXXXX\"\n  },\n  \"distinct_id\": \"user_12345\",\n  \"name\": \"John Doe\",\n  \"status\": 1,\n  \"timezone\": \"Asia/Kolkata\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Manage User Profiles_updateUserProfile_example
import Foundation

let headers = [
  "Authorization": "Bearer <apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "channel": [
    "email": "john@example.com",
    "push": [
      [
        "token": "device_token",
        "integration_id": "push_integration",
        "status": 1
      ]
    ],
    "sms": "+4XXXXXXXXXXX",
    "whatsapp": "+4XXXXXXXXXXX"
  ],
  "distinct_id": "user_12345",
  "name": "John Doe",
  "status": 1,
  "timezone": "Asia/Kolkata"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.fyno.io/v1/FYXXXXXXXX/version/profiles/XXXXXXXX")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```