# Semantic conventions for JSON-RPC

Site [llms.txt](/llms.txt)

---

**Status**: [Development][DocumentStatus]

<!-- START doctoc -->

- [Spans](#spans)
  - [Client](#client)
  - [Server](#server)
- [Metrics](#metrics)

<!-- END doctoc -->

The Semantic Conventions for [JSON-RPC](https://www.jsonrpc.org/) extend and override the [RPC Semantic Conventions](README.md).

## Spans

### Client

<!-- semconv span.rpc.jsonrpc.call.client -->
<!-- NOTE: THIS TEXT IS AUTOGENERATED. DO NOT EDIT BY HAND. -->
<!-- see templates/registry/markdown/snippet.md.j2 -->
<!-- prettier-ignore-start -->

**Status:** ![Development](https://img.shields.io/badge/-development-blue)

This span represents an outgoing Remote Procedure Call (RPC).

**Span name:** refer to the [Span Name](/docs/specs/semconv/rpc/rpc-spans.md#name) section.

**Span kind** MUST be `CLIENT`.

**Span status**: refer to the [Recording Errors](/docs/specs/semconv/general/recording-errors.md)
document for details on how to record span status. Responses that include
an [`error` object](https://www.jsonrpc.org/specification#error_object)
are considered errors.

**Attributes:**

| Key | Stability | [Requirement Level](/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
| --- | --- | --- | --- | --- | --- |
| [`rpc.system.name`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | The Remote Procedure Call (RPC) system. [1] | `jsonrpc` |
| [`error.type`](/docs/specs/semconv/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [2] | `DEADLINE_EXCEEDED`; `java.net.UnknownHostException`; `-32602` |
| [`jsonrpc.protocol.version`](/docs/specs/semconv/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If other than the default version (`1.0`) | string | Protocol version, as specified in the `jsonrpc` property of the request and its corresponding response. | `2.0`; `1.0` |
| [`rpc.method_original`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if it's different than `rpc.method`. | string | The original name of the method used by the client. | `com.myservice.EchoService/catchAll`; `com.myservice.EchoService/unknownMethod`; `InvalidMethod` |
| [`rpc.status_code`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` when available | string | The [`error.code`](https://www.jsonrpc.org/specification#error_object) property of response if it is an error response recorded as a string. [3] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
| [`server.port`](/docs/specs/semconv/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` if applicable and if `server.address` is set. | int | Server port number. [4] | `80`; `8080`; `443` |
| [`jsonrpc.request.id`](/docs/specs/semconv/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | A string representation of the `id` property of the request and its corresponding response. [5] | `10`; `request-7` |
| [`network.peer.address`](/docs/specs/semconv/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Peer address of the network connection - IP address or UNIX domain socket name. [6] | `10.1.2.80`; `/tmp/my.sock` |
| [`network.peer.port`](/docs/specs/semconv/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If `network.peer.address` is set. | int | Peer port number of the network connection. | `65123` |
| [`server.address`](/docs/specs/semconv/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` [7] | string | A string identifying a group of RPC server instances request is sent to. | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
| [`rpc.method`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Opt-In` | string | JSON-RPC method name provided in the request. [8] | `com.example.ExampleService/exampleMethod`; `EchoService/Echo`; `_OTHER` |
| [`rpc.request.header.<key>`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Opt-In` | string[] | RPC request headers or metadata, `<key>` being the normalized header name (lowercase), the value being the header values. [9] | `["1.2.3.4", "1.2.3.5"]` |
| [`rpc.response.header.<key>`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Opt-In` | string[] | RPC response headers or metadata sent before the response payload, `<key>` being the normalized header name (lowercase), the value being the header values. [10] | `["attribute_value"]` |
| [`rpc.response.trailer.<key>`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Opt-In` | string[] | RPC response trailers or metadata sent after the response payload, `<key>` being the normalized trailer name (lowercase), the value being the trailer values. [11] | `["attribute_value"]` |

**[1] `rpc.system.name`:** MUST be set to `jsonrpc`.

**[2] `error.type`:** If the RPC fails with an error before status code is returned,
`error.type` SHOULD be set to the exception type (its fully-qualified class name, if applicable)
or a component-specific, low cardinality error identifier.

If a status code is returned and it indicates an error,
`error.type` SHOULD be set to that status code. Check system-specific conventions
for the details on which values of `rpc.status_code` are considered errors.

The `error.type` value SHOULD be predictable and SHOULD have low cardinality.
Instrumentations SHOULD document the list of errors they report.

If the request has completed successfully, instrumentations SHOULD NOT set
`error.type`.

**[3] `rpc.status_code`:** All JSON RPC error codes SHOULD be considered errors.

Instrumentations MAY use additional context or provide configuration options to customize
which error codes are considered errors.

**[4] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.

**[5] `jsonrpc.request.id`:** Under the [JSON-RPC specification](https://www.jsonrpc.org/specification), the `id` property may be a string, number, null, or omitted entirely. When omitted, the request is treated as a notification. Using `null` is not equivalent to omitting the `id`, but it is discouraged.
Instrumentations SHOULD NOT capture this attribute when the `id` is `null` or omitted.

**[6] `network.peer.address`:** If a RPC involved multiple network calls (for example retries), the last contacted address SHOULD be used.

**[7] `server.address`:** Instrumentations that have access to the transport-level information and can reliably extract domain name or another low-cardinality server address from it SHOULD set this attribute.

**[8] `rpc.method`:** JSON-RPC supports sending and receiving arbitrary method names without prior registration or definition. As a result, the method name MAY have unbounded cardinality in edge or error cases.
General-purpose JSON-RPC instrumentations therefore SHOULD NOT set this attribute by default and SHOULD provide a way to configure the list of recognized RPC methods. When tracing instrumentation converts RPC method to `_OTHER`, it MUST also set `rpc.method_original` span attribute to the original value.

**[9] `rpc.request.header.<key>`:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured.
Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information.

For example, a header `my-custom-key` with value `["1.2.3.4", "1.2.3.5"]` SHOULD be recorded as
the `rpc.request.header.my-custom-key` attribute with value `["1.2.3.4", "1.2.3.5"]`

The attribute value MUST consist of either multiple header values as an array of
strings or a single-item array containing a possibly comma-concatenated string,
depending on the way the RPC library provides access to headers.

Values that the RPC system exposes as binary data, or that are otherwise not valid
UTF-8 strings, SHOULD be base64-encoded when recorded.

**[10] `rpc.response.header.<key>`:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured.
Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information.

For example, a header `my-custom-key` with value `["attribute_value"]` SHOULD be recorded as
the `rpc.response.header.my-custom-key` attribute with value `["attribute_value"]`

The attribute value MUST consist of either multiple header values as an array of
strings or a single-item array containing a possibly comma-concatenated string,
depending on the way the RPC library provides access to headers.

Values that the RPC system exposes as binary data, or that are otherwise not valid
UTF-8 strings, SHOULD be base64-encoded when recorded.

**[11] `rpc.response.trailer.<key>`:** Instrumentations SHOULD require an explicit configuration of which trailers are to be captured.
Including all response trailers can be a security risk - explicit configuration helps avoid leaking sensitive information.

For example, a trailer `my-custom-key` with value `["attribute_value"]` SHOULD be recorded as
the `rpc.response.trailer.my-custom-key` attribute with value `["attribute_value"]`

The attribute value MUST consist of either multiple trailer values as an array of
strings or a single-item array containing a possibly comma-concatenated string,
depending on the way the RPC library provides access to trailers.

Values that the RPC system exposes as binary data, or that are otherwise not valid
UTF-8 strings, SHOULD be base64-encoded when recorded.

The following attributes can be important for making sampling decisions
and SHOULD be provided **at span creation time** (if provided at all):

* [`rpc.method`](/docs/specs/semconv/registry/attributes/rpc.md)
* [`rpc.system.name`](/docs/specs/semconv/registry/attributes/rpc.md)
* [`server.address`](/docs/specs/semconv/registry/attributes/server.md)
* [`server.port`](/docs/specs/semconv/registry/attributes/server.md)

<!-- prettier-ignore-end -->
<!-- END AUTOGENERATED TEXT -->
<!-- endsemconv -->

### Server

<!-- semconv span.rpc.jsonrpc.call.server -->
<!-- NOTE: THIS TEXT IS AUTOGENERATED. DO NOT EDIT BY HAND. -->
<!-- see templates/registry/markdown/snippet.md.j2 -->
<!-- prettier-ignore-start -->

**Status:** ![Development](https://img.shields.io/badge/-development-blue)

This span represents an incoming Remote Procedure Call (RPC).

**Span name:** refer to the [Span Name](/docs/specs/semconv/rpc/rpc-spans.md#name) section.

**Span kind** MUST be `SERVER`.

**Span status**: refer to the [Recording Errors](/docs/specs/semconv/general/recording-errors.md)
document for details on how to record span status. Responses that include
an [`error` object](https://www.jsonrpc.org/specification#error_object)
are considered errors.

**Attributes:**

| Key | Stability | [Requirement Level](/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
| --- | --- | --- | --- | --- | --- |
| [`rpc.system.name`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | The Remote Procedure Call (RPC) system. [1] | `jsonrpc` |
| [`error.type`](/docs/specs/semconv/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [2] | `DEADLINE_EXCEEDED`; `java.net.UnknownHostException`; `-32602` |
| [`jsonrpc.protocol.version`](/docs/specs/semconv/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If other than the default version (`1.0`) | string | Protocol version, as specified in the `jsonrpc` property of the request and its corresponding response. | `2.0`; `1.0` |
| [`rpc.method_original`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if it's different than `rpc.method`. | string | The original name of the method used by the client. | `com.myservice.EchoService/catchAll`; `com.myservice.EchoService/unknownMethod`; `InvalidMethod` |
| [`rpc.status_code`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` when available | string | The [`error.code`](https://www.jsonrpc.org/specification#error_object) property of response recorded as a string. [3] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
| [`server.port`](/docs/specs/semconv/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` if applicable and if `server.address` is set. | int | Server port number. [4] | `80`; `8080`; `443` |
| [`jsonrpc.request.id`](/docs/specs/semconv/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | A string representation of the `id` property of the request and its corresponding response. [5] | `10`; `request-7` |
| [`network.peer.address`](/docs/specs/semconv/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Peer address of the network connection - IP address or UNIX domain socket name. [6] | `10.1.2.80`; `/tmp/my.sock` |
| [`network.peer.port`](/docs/specs/semconv/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If `network.peer.address` is set. | int | Peer port number of the network connection. | `65123` |
| [`server.address`](/docs/specs/semconv/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` when available. | string | A string identifying a group of RPC server instances request is sent to. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
| [`rpc.method`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Opt-In` | string | JSON-RPC method name provided in the request. [8] | `com.example.ExampleService/exampleMethod`; `EchoService/Echo`; `_OTHER` |
| [`rpc.request.header.<key>`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Opt-In` | string[] | RPC request headers or metadata, `<key>` being the normalized header name (lowercase), the value being the header values. [9] | `["1.2.3.4", "1.2.3.5"]` |
| [`rpc.response.header.<key>`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Opt-In` | string[] | RPC response headers or metadata sent before the response payload, `<key>` being the normalized header name (lowercase), the value being the header values. [10] | `["attribute_value"]` |
| [`rpc.response.trailer.<key>`](/docs/specs/semconv/registry/attributes/rpc.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Opt-In` | string[] | RPC response trailers or metadata sent after the response payload, `<key>` being the normalized trailer name (lowercase), the value being the trailer values. [11] | `["attribute_value"]` |

**[1] `rpc.system.name`:** MUST be set to `jsonrpc`.

**[2] `error.type`:** If the RPC fails with an error before status code is returned,
`error.type` SHOULD be set to the exception type (its fully-qualified class name, if applicable)
or a component-specific, low cardinality error identifier.

If a status code is returned and it indicates an error,
`error.type` SHOULD be set to that status code. Check system-specific conventions
for the details on which values of `rpc.status_code` are considered errors.

The `error.type` value SHOULD be predictable and SHOULD have low cardinality.
Instrumentations SHOULD document the list of errors they report.

If the request has completed successfully, instrumentations SHOULD NOT set
`error.type`.

**[3] `rpc.status_code`:** All JSON RPC error codes SHOULD be considered errors.

Instrumentations MAY use additional context or provide configuration options to customize
which error codes are considered errors.

**[4] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.

**[5] `jsonrpc.request.id`:** Under the [JSON-RPC specification](https://www.jsonrpc.org/specification), the `id` property may be a string, number, null, or omitted entirely. When omitted, the request is treated as a notification. Using `null` is not equivalent to omitting the `id`, but it is discouraged.
Instrumentations SHOULD NOT capture this attribute when the `id` is `null` or omitted.

**[6] `network.peer.address`:** If a RPC involved multiple network calls (for example retries), the last contacted address SHOULD be used.

**[7] `server.address`:** `server.address` and `server.port` describe the address the client used to reach this server, as reported by the transport or RPC framework. Instrumentations SHOULD NOT use actual network-level connection information to populate these attributes. If the address used by the client is unavailable, instrumentations SHOULD NOT set these attributes.

**[8] `rpc.method`:** JSON-RPC supports sending and receiving arbitrary method names without prior registration or definition. As a result, the method name MAY have unbounded cardinality in edge or error cases.
General-purpose JSON-RPC instrumentations therefore SHOULD NOT set this attribute by default and SHOULD provide a way to configure the list of recognized RPC methods. When tracing instrumentation converts RPC method to `_OTHER`, it MUST also set `rpc.method_original` span attribute to the original value.

**[9] `rpc.request.header.<key>`:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured.
Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information.

For example, a header `my-custom-key` with value `["1.2.3.4", "1.2.3.5"]` SHOULD be recorded as
the `rpc.request.header.my-custom-key` attribute with value `["1.2.3.4", "1.2.3.5"]`

The attribute value MUST consist of either multiple header values as an array of
strings or a single-item array containing a possibly comma-concatenated string,
depending on the way the RPC library provides access to headers.

Values that the RPC system exposes as binary data, or that are otherwise not valid
UTF-8 strings, SHOULD be base64-encoded when recorded.

**[10] `rpc.response.header.<key>`:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured.
Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information.

For example, a header `my-custom-key` with value `["attribute_value"]` SHOULD be recorded as
the `rpc.response.header.my-custom-key` attribute with value `["attribute_value"]`

The attribute value MUST consist of either multiple header values as an array of
strings or a single-item array containing a possibly comma-concatenated string,
depending on the way the RPC library provides access to headers.

Values that the RPC system exposes as binary data, or that are otherwise not valid
UTF-8 strings, SHOULD be base64-encoded when recorded.

**[11] `rpc.response.trailer.<key>`:** Instrumentations SHOULD require an explicit configuration of which trailers are to be captured.
Including all response trailers can be a security risk - explicit configuration helps avoid leaking sensitive information.

For example, a trailer `my-custom-key` with value `["attribute_value"]` SHOULD be recorded as
the `rpc.response.trailer.my-custom-key` attribute with value `["attribute_value"]`

The attribute value MUST consist of either multiple trailer values as an array of
strings or a single-item array containing a possibly comma-concatenated string,
depending on the way the RPC library provides access to trailers.

Values that the RPC system exposes as binary data, or that are otherwise not valid
UTF-8 strings, SHOULD be base64-encoded when recorded.

The following attributes can be important for making sampling decisions
and SHOULD be provided **at span creation time** (if provided at all):

* [`rpc.method`](/docs/specs/semconv/registry/attributes/rpc.md)
* [`rpc.system.name`](/docs/specs/semconv/registry/attributes/rpc.md)
* [`server.address`](/docs/specs/semconv/registry/attributes/server.md)
* [`server.port`](/docs/specs/semconv/registry/attributes/server.md)

<!-- prettier-ignore-end -->
<!-- END AUTOGENERATED TEXT -->
<!-- endsemconv -->

## Metrics

JSON-RPC instrumentations SHOULD collect metrics according to the general
[Semantic Conventions for RPC Metrics](/docs/specs/semconv/rpc/rpc-metrics.md).

`rpc.system.name` MUST be set to `"jsonrpc"`.

[DocumentStatus]: /docs/specs/otel/document-status/
