diff --git a/develop-docs/sdk/telemetry/profiles/index.mdx b/develop-docs/sdk/telemetry/profiles/index.mdx
index 20355c3febc3b..0e2c1a053fc33 100644
--- a/develop-docs/sdk/telemetry/profiles/index.mdx
+++ b/develop-docs/sdk/telemetry/profiles/index.mdx
@@ -9,411 +9,3 @@ ingestion pipeline.
This format is meant to be cross platform and allow to represent samples
collected by a profiler.
-
-A profile should always be associated with a transaction and it should be sent
-in the same envelope as the associated transaction.
-
-## Data Model
-
-### Example
-
-```json
-{
- "debug_meta": {
- "images": [
- {
- "debug_id": "32420279-25E2-34E6-8BC7-8A006A8F2425",
- "image_addr": "0x000000010258c000",
- "code_file": "/private/var/containers/Bundle/Application/C3511752-DD67-4FE8-9DA2-ACE18ADFAA61/TrendingMovies.app/TrendingMovies",
- "type": "macho",
- "image_size": 1720320,
- "image_vmaddr": "0x0000000100000000"
- }
- ]
- },
- "device": {
- "architecture": "arm64e",
- "is_emulator": true,
- "locale": "en_US",
- "manufacturer": "Apple",
- "model": "iPhone14,8"
- },
- "environment": "development",
- "event_id": "41fed0925670468bb0457f61a74688ec",
- "measurements": { ... },
- "os": {
- "build_number": "20D47",
- "name": "iOS",
- "version": "16.3",
- },
- "platform": "cocoa",
- "release": "1.0 (9999)",
- "runtime": {
- "name": "",
- "version": ""
- },
- "timestamp": "2023-01-01T00:00:00.000Z",
- "transaction": {
- "active_thread_id": "259",
- "id": "30976f2ddbe04ac9b6bffe6e35d4710c",
- "name": "example_ios_movies_sources.MoviesViewController",
- "trace_id": "4b25bc58f14243d8b208d1e22a054164",
- },
- "version": "1",
- "profile": {
- "samples": [
- {
- "elapsed_since_start_ns": 1234567890,
- "stack_id": 0,
- "thread_id": "259"
- }
- ],
- "stacks": [
- [ 0 ]
- ],
- "frames": [
- {
- "instruction_addr": "0xa722447ffffffffc"
- }
- ],
- "thread_metadata": {
- "259": {
- "priority": 31
- }
- }
- },
-}
-```
-
-### Profile metadata
-
-`debug_meta`
-
-: *Object, required on native platforms.* This carry the same payload as `debug_meta` interface. It is required to
-have it for native platforms in order to symbolicate, otherwise you can omit it.
-
-`device`
-
-: *Object, required.* This contains a few fields to describe the device the
-profiler is running on.
-
-It can have the following attributes:
-- `architecture`: *String, required.*
-- `is_emulator`: *Boolean, optional.* Indicates if the application is running in an emulator. Usually only set for mobile platforms.
-- `locale`: *String, optional.* Contains the local of the system. Usually only set for a mobile platforms.
-- `manufacturer`: *String, optional.* Contains the manufacturer of the device. Usually only set for a mobile platforms.
-- `model`: *String, optional.* Contains the model of the device. Usually only set for a mobile platforms.
-
-```json
-{
- "device": {
- "architecture": "arm64e",
- "is_emulator": true,
- "locale": "en_US",
- "manufacturer": "Apple",
- "model": "iPhone14,8"
- }
-}
-```
-
-`environment`
-
-: *String, recommended.* The environment name, such as `production` or
-`staging`. The default value should be `production`.
-
-`event_id`
-
-: *String, required.* Hexadecimal string representing a uuid4 value. The length
-is exactly 32 characters. Dashes are not allowed. Has to be lowercase.
-
-`measurements`
-
-: *Object, optional.* This field contains various metrics measured during the profile collection.
-
-A measurement is a collection of measurement values and a unit for those values.
-It will only be shown in the UI if it's been integrated. Right now, we only
-support 2 metrics:
-- `frozen_frame_renders`: when a frozen frame was detected.
-- `slow_frame_renders`: when a slow frame was detected.
-
-A measurement value can contain the following attributes:
-- `elapsed_since_start_ns`: number of nanoseconds since the start of the profile
- (stored in `timestamp`). It should be wall time.
-- `value`: value for the measurement, as a `float64`. We accept `float64`
- formatted as `string` as well.
-
-These are the values accepted for `unit`:
-- `nanosecond`
-- `ns`
-- `hertz`
-- `hz`
-- `byte`
-- `percent`
-
-```json
-{
- "cpu_0": {
- "unit": "percent",
- "values": {
- "elapsed_since_start_ns: "1234567890",
- "value": 12.64,
- }
- }
-}
-```
-
-`os`
-
-: *Object, required.* Contains information about the OS.
-
-
-It can have the following attributes:
-- `name`: *String, required.* Contains the OS name.
-- `version`: *String, required.* Contains the OS version.
-- `build_number`: *String, optional.* Only set it for `cocoa` platform.
-
-```json
-{
- "os": {
- "build_number": "20D47",
- "name": "iOS",
- "version": "16.3",
- }
-}
-```
-
-`platform`
-
-: *String, required.* This value represents the platform the SDK is submitting
-from.
-
-Acceptable values are:
-- `cocoa`
-- `node`
-- `python`
-- `rust`
-
-`profile`
-
-: *Object, required.* It contains all the raw data collected when profiling. See
-[profile data](#profile-data).
-
-`release`
-
-: *String, required.* The release version of the application.
-
-**Release versions must be unique across all projects in your organization**.
-This value can be the git SHA for the given project, or a product identifier
-with a semantic version (suggested format `my-project-name@1.0.0`).
-
-`runtime`
-
-: *Object, optional.* Contains information about the runtime. Usually only used
-for platforms allowing several runtimes.
-
-It can have the following attributes:
-- `name`
-- `version`
-
-```json
-{
- "runtime": {
- "name": "CPython",
- "version": "3.11.2"
- }
-}
-```
-
-`timestamp`
-
-: *String, recommended.* The timestamp when the profile was captured by the SDK
-as [RFC 3339](https://tools.ietf.org/html/rfc3339) format. This is meant to be
-the anchor for all relative timestamps captured for the profile.
-
-Ideally, this will be the same as the field `start_timestamp` on the transaction
-so all relative timestamps for transaction and profile can be both from the same
-reference point and we don't need to correct relative timestamps.
-
-If for some reasons, the profiler implementation doesn't allow that, set it to
-the closest time to the profiler start (or to whatever the profiler gives you as
-a profile start timestamp) and it will be used to align with the transaction
-later on.
-
-`transaction`
-
-: *Object, required.* Contains information about the transaction it is
-associated with.
-
-It can have the following attributes:
-- `id`: *String, required.* Contains the transaction ID.
-- `name`: *String, required.* Contains the name of the transaction.
-- `trace_id`: *String, required.* Contains the trace ID the transaction is part
- of.
-- `active_thread_id`: *String, required.* Contains the thread ID the transaction
- was started on as `uint64` converted to a string. On mobile, this is usually
- the main thread.
-
-`version`
-
-: *String, required.* Represents the version of the Sample format.
-
-Acceptable values are:
-- `"1"`
-
-### Profile data
-
-The profile data consists of
-- sample, which specifies the start time, their corresponding thread and a stack,
-- stacks, which are lists of frames,
-- frames, which identify the function and/or line of code for each item in a stacktrace,
-- thread metadata, with info about threads.
-
-The selected format is trying to keep the amount of data we transfer to the server as limited as possible.
-
-```json
-{
- "profile": {
- "samples": [
- { ... },
- ...
- ],
- "stacks": [
- [ ... ],
- ...
- ],
- "frames": [
- { ... },
- ...
- ],
- "thread_metadata": {
- "259": {
- ...
- }
- }
- }
-}
-```
-
-When collecting a stack trace, you will:
-1. Capture the stack trace.
-2. Capture a timestamp relative to the start of the profile (set in the
-`timestamp` field).
-3. Capture the thread ID where this stack trace was captured.
-4. Create a list of indices for each frames (add it to the frame list if needed
-or use the existing frame's index).
-5. Check if that stack exists in the list of stacks and if it doesn't, add it to the list of stacks
-6. Create a sample containing the thread ID, the relative timestamp and the
-stack ID.
-
-You should collect samples at a frequency of 101Hz, or roughly once every 10
-milliseconds.
-
-`samples`
-
-: *List, required* Contains a list of sample object captured during execution.
-Each sample can contain the following attributes:
-
-- `elapsed_since_start_ns`: *String, required.* Contains the relative timestamp
- in nanoseconds since the value contained in the `timestamp` field when the
- sample was captured. It's meant to be a `uint64` formatted as a `string`, a
- `float` won't be accepted. It should be wall time.
-- `stack_id`: *Integer, required.* Contains the stack index from the `stacks` list.
-- `thread_id`: *String, required.* Contains the thread ID on which the sample was captured.
-
-```json
-{
- "elapsed_since_start_ns": "1234567890",
- "stack_id": 1,
- "thread_id": "259",
-}
-```
-
-`stacks`
-
-: *List, required*. Contains a list of frame indices forming a stack trace.
-
-Frames in a stack should be ordered from leaf to root. It means your main frame
-should be at the end of the list.
-
-It's encouraged to deduplicate stacks by only storing it once and referring to
-the same `stack_id` for each sample that needs it.
-
-`frames`
-
-: *List, required*. Contains a list of frame objects (see [Frame
-Attributes](/sdk/event-payloads/stacktrace/#frame-attributes)).
-
-Each object should contain at least a `filename`, `function` or
-`instruction_addr` attribute. All values are optional, but recommended.
-
-For native platforms (`cocoa` or `rust` for example), `instruction_addr` is
-required in order to be able to symbolicate and get more info about the frame.
-
-For the rest of the platforms, whatever is passed here will travel to the
-frontend and whatever is available can be used to show more or less information.
-
-We will use `module` or `package` (in that order) to group frames when needed.
-
-Some attributes are not used at the moment:
-- `raw_function`
-- `pre_context`
-- `post_context`
-- `stack_start`
-- `vars`
-- `addr_mode`
-- `platform`
-
-`thread_metadata`
-
-: *Object, required.* Contains an object with a field for each thread ID
-detected during runtime.
-
-This object can contain these attributes:
-- `name`: name of the thread.
-- `priority`: the priority of the thread.
-
-This information will be used on the flamechart to power the thread selector.
-
-```json
-{
- "thread_metadata": {
- "259": {
- "name": "com.apple.main-thread",
- "priority": 31
- }
- }
-}
-```
-
-## Validation
-
-We will reject a profile in Relay for several reasons:
-- profile data is missing (no frame, no sample, no stack)
-- not enough samples (we need at least 2 samples)
-- no transaction associated with the profile
-- any of the metadata required is missing
-- size of the profile exceeds 50MB
-- a profile exceeds 30 seconds (difference between last and first sample
- timestamp)
-
-It is suggested to validate these conditions before sending the profile.
-
-It's suggested to remove unnecessary data like thread data without samples from
-`thread_metadata`.
-
-## Ingestion
-
-After this payload is generated, serialize it as JSON, pack it into the same
-[Envelope](/sdk/envelopes/) as the associated transaction with the item type
-[`profile`](/sdk/envelopes/#profile) and send it to Relay.
-
-This envelope should look like this:
-
-```json
-{"event_id":"a229377b82ad4898be7c3a6272d052d9"}
-{"type":"transaction"}
-{ /* transaction JSON payload */ }
-{"type":"profile"}
-{ /* profile JSON payload */}
-````
diff --git a/develop-docs/sdk/telemetry/profiles/sample-format-v1.mdx b/develop-docs/sdk/telemetry/profiles/sample-format-v1.mdx
new file mode 100644
index 0000000000000..5600a83ca49db
--- /dev/null
+++ b/develop-docs/sdk/telemetry/profiles/sample-format-v1.mdx
@@ -0,0 +1,412 @@
+---
+title: Sample Format V1
+sidebar_order: 40
+---
+
+For the *Sample Format V1*, a profile should always be associated with a transaction and it should be sent
+in the same envelope as the associated transaction.
+
+## Data Model
+
+### Example
+
+```json
+{
+ "debug_meta": {
+ "images": [
+ {
+ "debug_id": "32420279-25E2-34E6-8BC7-8A006A8F2425",
+ "image_addr": "0x000000010258c000",
+ "code_file": "/private/var/containers/Bundle/Application/C3511752-DD67-4FE8-9DA2-ACE18ADFAA61/TrendingMovies.app/TrendingMovies",
+ "type": "macho",
+ "image_size": 1720320,
+ "image_vmaddr": "0x0000000100000000"
+ }
+ ]
+ },
+ "device": {
+ "architecture": "arm64e",
+ "is_emulator": true,
+ "locale": "en_US",
+ "manufacturer": "Apple",
+ "model": "iPhone14,8"
+ },
+ "environment": "development",
+ "event_id": "41fed0925670468bb0457f61a74688ec",
+ "measurements": { ... },
+ "os": {
+ "build_number": "20D47",
+ "name": "iOS",
+ "version": "16.3",
+ },
+ "platform": "cocoa",
+ "release": "1.0 (9999)",
+ "runtime": {
+ "name": "",
+ "version": ""
+ },
+ "timestamp": "2023-01-01T00:00:00.000Z",
+ "transaction": {
+ "active_thread_id": "259",
+ "id": "30976f2ddbe04ac9b6bffe6e35d4710c",
+ "name": "example_ios_movies_sources.MoviesViewController",
+ "trace_id": "4b25bc58f14243d8b208d1e22a054164",
+ },
+ "version": "1",
+ "profile": {
+ "samples": [
+ {
+ "elapsed_since_start_ns": 1234567890,
+ "stack_id": 0,
+ "thread_id": "259"
+ }
+ ],
+ "stacks": [
+ [ 0 ]
+ ],
+ "frames": [
+ {
+ "instruction_addr": "0xa722447ffffffffc"
+ }
+ ],
+ "thread_metadata": {
+ "259": {
+ "priority": 31
+ }
+ }
+ },
+}
+```
+
+### Profile metadata
+
+`debug_meta`
+
+: *Object, required on native platforms.* This carries the same payload as the `debug_meta` interface. It is required to
+have it for native platforms in order to symbolicate. For non-native platforms, you can omit this.
+
+`device`
+
+: *Object, required.* This contains several fields that describe the device the
+profiler is running on.
+
+It can have the following attributes:
+- `architecture`: *String, required.*
+- `is_emulator`: *Boolean, optional.* Indicates if the application is running in an emulator. Usually only set for mobile platforms.
+- `locale`: *String, optional.* Contains the local of the system. Usually only set for a mobile platforms.
+- `manufacturer`: *String, optional.* Contains the manufacturer of the device. Usually only set for mobile platforms.
+- `model`: *String, optional.* Contains the model of the device. Usually only set for mobile platforms.
+
+```json
+{
+ "device": {
+ "architecture": "arm64e",
+ "is_emulator": true,
+ "locale": "en_US",
+ "manufacturer": "Apple",
+ "model": "iPhone14,8"
+ }
+}
+```
+
+`environment`
+
+: *String, recommended.* The environment name, such as `production` or
+`staging`. The default value is `production`.
+
+`event_id`
+
+: *String, required.* Hexadecimal string representing a uuid4 value. The length
+must be exactly 32 characters. Dashes and uppercase letters are not allowed.
+
+`measurements`
+
+: *Object, optional.* This field contains various metrics measured during the profile collection.
+
+A measurement is a collection of measurement values and a unit for those values.
+It will only be shown in the UI if it's been integrated. Right now, we only
+support 2 metrics:
+- `frozen_frame_renders`: when a frozen frame was detected.
+- `slow_frame_renders`: when a slow frame was detected.
+
+A measurement value can contain the following attributes:
+- `elapsed_since_start_ns`: number of nanoseconds since the start of the profile
+ (stored in `timestamp`). It should be wall time.
+- `value`: value for the measurement, as a `float64`. We accept `float64`
+ formatted as `string` as well.
+
+These are the values accepted for `unit`:
+- `nanosecond`
+- `ns`
+- `hertz`
+- `hz`
+- `byte`
+- `percent`
+
+```json
+{
+ "cpu_0": {
+ "unit": "percent",
+ "values": {
+ "elapsed_since_start_ns: "1234567890",
+ "value": 12.64,
+ }
+ }
+}
+```
+
+`os`
+
+: *Object, required.* Contains information about the OS.
+
+
+It can have the following attributes:
+- `name`: *String, required.* Contains the OS name.
+- `version`: *String, required.* Contains the OS version.
+- `build_number`: *String, optional.* Only set it for `cocoa` platform.
+
+```json
+{
+ "os": {
+ "build_number": "20D47",
+ "name": "iOS",
+ "version": "16.3",
+ }
+}
+```
+
+`platform`
+
+: *String, required.* This value represents the platform the SDK is submitting
+from.
+
+Acceptable values are:
+- `cocoa`
+- `node`
+- `python`
+- `rust`
+
+`profile`
+
+: *Object, required.* It contains all the raw data collected when profiling. See
+[profile data](#profile-data).
+
+`release`
+
+: *String, required.* The release version of the application.
+
+**Release versions must be unique across all projects in your organization**.
+This value can be the git SHA for the given project, or a product identifier
+with a semantic version (suggested format `my-project-name@1.0.0`).
+
+`runtime`
+
+: *Object, optional.* Contains information about the runtime. Usually only used
+for platforms allowing several runtimes.
+
+It can have the following attributes:
+- `name`
+- `version`
+
+```json
+{
+ "runtime": {
+ "name": "CPython",
+ "version": "3.11.2"
+ }
+}
+```
+
+`timestamp`
+
+: *String, recommended.* The timestamp when the profile was captured by the SDK
+as [RFC 3339](https://tools.ietf.org/html/rfc3339) format. This is meant to be
+the anchor for all relative timestamps captured for the profile.
+
+Ideally, this will be the same as the field `start_timestamp` on the transaction
+so all relative timestamps for transaction and profile can be both from the same
+reference point and we don't need to correct relative timestamps.
+
+If for some reasons, the profiler implementation doesn't allow that, set it to
+the closest time to the profiler start (or to whatever the profiler gives you as
+a profile start timestamp) and it will be used to align with the transaction
+later on.
+
+`transaction`
+
+: *Object, required.* Contains information about the transaction it is
+associated with.
+
+It can have the following attributes:
+- `id`: *String, required.* Contains the transaction ID.
+- `name`: *String, required.* Contains the name of the transaction.
+- `trace_id`: *String, required.* Contains the trace ID the transaction is part
+ of.
+- `active_thread_id`: *String, required.* Contains the thread ID the transaction
+ was started on as `uint64` converted to a string. On mobile, this is usually
+ the main thread.
+
+`version`
+
+: *String, required.* Represents the version of the Sample format.
+
+Acceptable values are:
+- `"1"`
+
+### Profile data
+
+The profile data consists of
+- sample, which specifies the start time, their corresponding thread and a stack,
+- stacks, which are lists of frames,
+- frames, which identify the function and/or line of code for each item in a stacktrace,
+- thread metadata, with info about threads.
+
+The selected format is trying to keep the amount of data we transfer to the server as limited as possible.
+
+```json
+{
+ "profile": {
+ "samples": [
+ { ... },
+ ...
+ ],
+ "stacks": [
+ [ ... ],
+ ...
+ ],
+ "frames": [
+ { ... },
+ ...
+ ],
+ "thread_metadata": {
+ "259": {
+ ...
+ }
+ }
+ }
+}
+```
+
+When collecting a stack trace, you will:
+1. Capture the stack trace.
+2. Capture a timestamp relative to the start of the profile (set in the
+`timestamp` field).
+3. Capture the thread ID where this stack trace was captured.
+4. Create a list of indices for each frames (add it to the frame list if needed
+or use the existing frame's index).
+5. Check if that stack exists in the list of stacks and if it doesn't, add it to the list of stacks
+6. Create a sample containing the thread ID, the relative timestamp and the
+stack ID.
+
+You should collect samples at a frequency of 101Hz, or roughly once every 10
+milliseconds.
+
+`samples`
+
+: *List, required* Contains a list of sample object captured during execution.
+Each sample can contain the following attributes:
+
+- `elapsed_since_start_ns`: *String, required.* Contains the relative timestamp
+ in nanoseconds since the value contained in the `timestamp` field when the
+ sample was captured. It's meant to be a `uint64` formatted as a `string`, a
+ `float` won't be accepted. It should be wall time.
+- `stack_id`: *Integer, required.* Contains the stack index from the `stacks` list.
+- `thread_id`: *String, required.* Contains the thread ID on which the sample was captured.
+
+```json
+{
+ "elapsed_since_start_ns": "1234567890",
+ "stack_id": 1,
+ "thread_id": "259",
+}
+```
+
+`stacks`
+
+: *List, required*. Contains a list of frame indices forming a stack trace.
+
+Frames in a stack should be ordered from leaf to root. It means your main frame
+should be at the end of the list.
+
+It's encouraged to deduplicate stacks by only storing it once and referring to
+the same `stack_id` for each sample that needs it.
+
+`frames`
+
+: *List, required*. Contains a list of frame objects (see [Frame
+Attributes](/sdk/event-payloads/stacktrace/#frame-attributes)).
+
+Each object should contain at least a `filename`, `function` or
+`instruction_addr` attribute. All values are optional, but recommended.
+
+For native platforms (`cocoa` or `rust` for example), `instruction_addr` is
+required in order to be able to symbolicate and get more info about the frame.
+
+For the rest of the platforms, whatever is passed here will travel to the
+frontend and whatever is available can be used to show more or less information.
+
+We will use `module` or `package` (in that order) to group frames when needed.
+
+Some attributes are not used at the moment:
+- `raw_function`
+- `pre_context`
+- `post_context`
+- `stack_start`
+- `vars`
+- `addr_mode`
+- `platform`
+
+`thread_metadata`
+
+: *Object, required.* Contains an object with a field for each thread ID
+detected during runtime.
+
+This object can contain these attributes:
+- `name`: name of the thread.
+- `priority`: the priority of the thread.
+
+This information will be used on the flamechart to power the thread selector.
+
+```json
+{
+ "thread_metadata": {
+ "259": {
+ "name": "com.apple.main-thread",
+ "priority": 31
+ }
+ }
+}
+```
+
+## Validation
+
+We will reject a profile in Relay for several reasons:
+- profile data is missing (no frame, no sample, no stack)
+- not enough samples (we need at least 2 samples)
+- no transaction associated with the profile
+- any of the metadata required is missing
+- size of the profile exceeds 50MB
+- a profile exceeds 30 seconds (difference between last and first sample
+ timestamp)
+
+It is suggested to validate these conditions before sending the profile.
+
+It's suggested to remove unnecessary data like thread data without samples from
+`thread_metadata`.
+
+## Ingestion
+
+After this payload is generated, serialize it as JSON, pack it into the same
+[Envelope](/sdk/envelopes/) as the associated transaction with the item type
+[`profile`](/sdk/envelopes/#profile) and send it to Relay.
+
+This envelope should look like this:
+
+```json
+{"event_id":"a229377b82ad4898be7c3a6272d052d9"}
+{"type":"transaction"}
+{ /* transaction JSON payload */ }
+{"type":"profile"}
+{ /* profile JSON payload */}
+````
diff --git a/develop-docs/sdk/telemetry/profiles/sample-format-v2.mdx b/develop-docs/sdk/telemetry/profiles/sample-format-v2.mdx
new file mode 100644
index 0000000000000..e8154ce7ed3db
--- /dev/null
+++ b/develop-docs/sdk/telemetry/profiles/sample-format-v2.mdx
@@ -0,0 +1,303 @@
+---
+title: Sample Format V2
+sidebar_order: 40
+---
+
+The *Sample Format V2* is designed for use in continuous profiling. Therefore, a profile can exist independently and be sent in the envelope on its own.
+
+## Data Model
+
+### Example
+
+```json
+{
+ "debug_meta": {
+ "images": [
+ {
+ "debug_id": "5819FF25-01CB-3D32-B84F-0634B37D3BBC",
+ "image_addr": "0x00000001023a8000",
+ "type": "macho",
+ "image_size": 16384,
+ "code_file": "/Library/Developer/CoreSimulator/Volumes/iOS_21C62/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.2.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libLogRedirect.dylib"
+ }
+ ]
+ },
+ "profiler_id": "71bba98d90b545c39f2ae73f702d7ef4",
+ "chunk_id": "3e11a5c9831f4e49939c0a81944ea2cb",
+ "client_sdk": {
+ "name": "sentry.cocoa",
+ "version": "8.36.0"
+ },
+ "measurements": { ... },
+ "platform": "cocoa",
+ "release": "io.sentry.sample.iOS-Swift@8.36.0+1",
+ "environment": "simulator",
+ "version": "2",
+ "profile": {
+ "samples": [
+ {
+ "thread_id": "259",
+ "stack_id": 0,
+ "timestamp": 1724777211.5037799
+ }
+ ],
+ "stacks": [
+ [ 0 ]
+ ],
+ "frames": [
+ {
+ "instruction_addr": "0x000000010232d144",
+ "function": "_ZNK5dyld311MachOLoaded17findClosestSymbolEyPPKcPy"
+ }
+ ],
+ "thread_metadata": {
+ "259": {
+ "name": "main"
+ }
+ }
+ }
+}
+```
+
+### Profile metadata
+
+`debug_meta`
+
+: *Object, required on native platforms.* This carries the same payload as the `debug_meta` interface. It is required to
+have it for native platforms in order to symbolicate, otherwise you can omit it.
+For non-native platforms, you can omit this.
+
+`profiler_id`
+
+: *String, required.* Hexadecimal string representing a uuid4 value. The length
+must be exactly 32 characters. Dashes and uppercase letters are not allowed.
+Random UUID for each profiler session.
+
+`chunk_id`
+
+: *String, required.* Hexadecimal string representing a uuid4 value. The length
+must be exactly 32 characters. Dashes and uppercase letters are not allowed.
+This is a Random UUID identifying a chunk.
+
+`client_sdk`
+
+: *Object, optional.* Contains information about the client *SDK*.
+
+It can have the following attributes:
+- `name`
+- `version`
+
+`measurements`
+
+: *Object, optional.* This field contains various metrics measured during the profile collection.
+
+A measurement is a collection of measurement values and a unit for those values.
+It will only be shown in the UI if it's been integrated. Right now, we only
+support 2 metrics:
+- `frozen_frame_renders`: when a frozen frame was detected.
+- `slow_frame_renders`: when a slow frame was detected.
+
+A measurement value can contain the following attributes:
+- `timestamp`: UNIX timestamp in seconds with microseconds precision as a `float64`.
+- `value`: value for the measurement, as a `float64`. We accept `float64`
+ formatted as `string` as well.
+
+These are the values accepted for `unit`:
+- `nanosecond`
+- `ns`
+- `hertz`
+- `hz`
+- `byte`
+- `percent`
+
+```json
+{
+ "cpu_0": {
+ "unit": "percent",
+ "values": {
+ "timestamp": 1724777211.6403089,
+ "value": 12.64,
+ }
+ }
+}
+```
+
+`platform`
+
+: *String, required.* This value represents the platform the SDK is submitting
+from.
+
+`release`
+
+: *String, required.* The release version of the application.
+
+**Release versions must be unique across all projects in your organization**.
+This value can be the git SHA for the given project, or a product identifier
+with a semantic version (suggested format `my-project-name@1.0.0`).
+
+`environment`
+
+: *String, recommended.* The environment name, such as `production` or
+`staging`. The default value is `production`.
+
+`version`
+
+: *String, required.* Represents the version of the Sample format.
+
+Acceptable values are:
+- `"2"`
+
+`profile`
+
+: *Object, required.* It contains all the raw data collected when profiling. See
+[profile data](#profile-data).
+
+
+### Profile data
+
+The profile data consists of
+- sample, which specifies the start time, their corresponding thread and a stack,
+- stacks, which are lists of frames,
+- frames, which identify the function and/or line of code for each item in a stacktrace,
+- thread metadata, with info about threads.
+
+The selected format is trying to keep the amount of data we transfer to the server as limited as possible.
+
+```json
+{
+ "profile": {
+ "samples": [
+ { ... },
+ ...
+ ],
+ "stacks": [
+ [ ... ],
+ ...
+ ],
+ "frames": [
+ { ... },
+ ...
+ ],
+ "thread_metadata": {
+ "259": {
+ ...
+ }
+ }
+ }
+}
+```
+
+When collecting a stack trace, you will:
+1. Capture the stack trace.
+2. Capture an absolute timestamp of when the stack trace was "captured".
+3. Capture the thread ID where this stack trace was captured.
+4. Create a list of indices for each frames (add it to the frame list if needed
+or use the existing frame's index).
+5. Check if that stack exists in the list of stacks and if it doesn't, add it to the list of stacks
+6. Create a sample containing the thread ID, the timestamp and the
+stack ID.
+
+You should collect samples at a frequency of 101Hz, or roughly once every 10
+milliseconds.
+
+`samples`
+
+: *List, required* Contains a list of sample object captured during execution.
+Each sample can contain the following attributes:
+
+- `timestamp`: *64-bit floating point, required.* Contains the Unix timestamp in seconds with microseconds precision.
+ in seconds with millisecond precision when the sample was captured.
+- `stack_id`: *Integer, required.* Contains the stack index from the `stacks` list.
+- `thread_id`: *String, required.* Contains the thread ID on which the sample was captured.
+
+```json
+ {
+ "timestamp": 1724762625.5756555,
+ "thread_id": "6154596352",
+ "stack_id": 0
+ }
+```
+
+`stacks`
+
+: *List, required*. Contains a list of frame indices forming a stack trace.
+
+Frames in a stack should be ordered from leaf to root. It means your main frame
+should be at the end of the list.
+
+It's encouraged to deduplicate stacks by only storing it once and referring to
+the same `stack_id` for each sample that needs it.
+
+`frames`
+
+: *List, required*. Contains a list of frame objects (see [Frame
+Attributes](/sdk/event-payloads/stacktrace/#frame-attributes)).
+
+Each object should contain at least a `filename`, `function` or
+`instruction_addr` attribute. All values are optional, but recommended.
+
+For native platforms (`cocoa` for example), `instruction_addr` is
+required in order to be able to symbolicate and get more info about the frame.
+
+For the rest of the platforms, whatever is passed here will travel to the
+frontend and whatever is available can be used to show more or less information.
+
+We will use `module` or `package` (in that order) to group frames when needed.
+
+Some attributes are not used at the moment:
+- `raw_function`
+- `pre_context`
+- `post_context`
+- `stack_start`
+- `vars`
+- `addr_mode`
+- `platform`
+
+`thread_metadata`
+
+: *Object, required.* Contains an object with a field for each thread ID
+detected during runtime.
+
+This object can contain these attributes:
+- `name`: name of the thread.
+- `priority`: the priority of the thread.
+
+This information will be used on the flamechart to power the thread selector.
+
+```json
+{
+ "thread_metadata": {
+ "259": {
+ "name": "com.apple.main-thread",
+ "priority": 31
+ }
+ }
+}
+```
+
+## Validation
+
+We will reject a chunk (profile) in Relay for several reasons:
+- chunk data is missing (no frame, no sample, no stack)
+- any of the metadata required is missing
+- size of the chunk exceeds 50MB
+
+It is suggested to validate these conditions before sending the chunk.
+
+It's suggested to remove unnecessary data like thread data without samples from
+`thread_metadata`.
+
+## Ingestion
+
+After this payload is generated, serialize it as JSON, pack it into an
+[Envelope](/sdk/envelopes/) with the item type `profile_chunk` and send
+it to Relay.
+
+This envelope should look like this:
+
+```json
+{"event_id":"a229377b82ad4898be7c3a6272d052d9"}
+{"type":"profile_chunk"}
+{ /* profile_chunk JSON payload */}
+````
\ No newline at end of file