Transaction APIedit

The APM Server exposes an API Endpoint to send transaction records. Unless you are implementing an agent, you don’t need to know about the specifics of this API.

The following section contains information about:

Endpointedit

To send a transaction record you need to send a HTTP POST request to the APM Server transactions endpoint:

http(s)://{hostname}:{port}/v1/transactions

To send a record for a frontend transaction (see experimental frontend support), you need to send a HTTP POST request to the APM Server frontend transactions endpoint:

http(s)://{hostname}:{port}/v1/client-side/transactions

Information pertaining to the record must be sent as a JSON object.

Schema Definitionedit

The APM Server uses a JSON Schema for validating the transaction requests. Find details on how the schema is defined:

Payloadedit

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/transactions/payload.json",
    "title": "Transactions payload",
    "description": "List of transactions wrapped in an object containing some other attributes normalized away from the transactions themselves",
    "type": "object",
    "properties": {
        "service": {
            "$ref": "../service.json"
        },
        "process": {
            "$ref": "../process.json"
        },
        "system": {
            "$ref": "../system.json"
        },
        "transactions": {
            "type": "array",
            "items": {
                "$ref": "transaction.json"
            },
            "minItems": 1
        }
    },
    "required": ["service", "transactions"]
}

Transactionedit

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/transactions/transaction.json",
    "type": "object",
    "description": "Data captured by an agent representing an event occurring in a monitored service",
    "properties": {
        "context": {
            "$ref": "../context.json"
        },
        "duration": {
            "type": "number",
            "description": "How long the transaction took to complete, in ms with 3 decimal points"
        },
        "id": {
            "type": "string",
            "description": "UUID for the transaction, referred by its spans",
            "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
        },
        "name": {
            "type": "string",
            "description": "Generic designation of a transaction in the scope of a single service (eg: 'GET /users/:id')",
            "maxLength": 1024
        },
        "result": {
          	"type": "string",
          	"description": "The result of the transaction. HTTP status code for HTTP-related transactions.",
            "maxLength": 1024
        },
        "timestamp": {
            "type": "string",
            "pattern": "Z$",
            "format": "date-time",
            "description": "Recorded time of the transaction, UTC based and formatted as YYYY-MM-DDTHH:mm:ss.sssZ"
        },
        "spans": {
            "type": ["array", "null"],
            "items": {
                "$ref": "span.json"
            },
            "minItems": 0
        },
        "type": {
            "type": "string",
            "description": "Keyword of specific relevance in the service's domain (eg: 'request', 'backgroundjob', etc)",
            "maxLength": 1024
        },
        "marks": {
            "type": ["object", "null"],
            "description": "A mark captures the timing of a significant event during the lifetime of a transaction. Marks are organized into groups and can be set by the user or the agent.",
            "regexProperties": true,
            "patternProperties": {
                "^[^.*\"]*$": {
                    "$ref": "mark.json",
                    "maxLength": 1024
                }
            },
            "additionalProperties": false
        },
        "sampled": {
            "type": ["boolean", "null"],
            "description": "Transactions that are 'sampled' will include all available information. Transactions that are not sampled will not have 'spans' or 'context'. Defaults to true."
        },
        "span_count": {
            "type": ["object", "null"],
            "properties": {
                "dropped": {
                    "type": ["object", "null"],
                    "properties": {
                        "total": {
                            "type": ["number","null"],
                            "description": "Number of spans that have been dropped by the agent recording the transaction."
                        }
                    }
                }
            }
        }
    },
    "required": ["id", "name", "duration", "type", "timestamp"]
}

Spanedit

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/transactions/span.json",
    "type": "object",
    "properties": {
        "id": {
            "type": ["number", "null"],
            "description": "The locally unique ID of the span."
        },
        "context": {
            "type": ["object", "null"],
            "description": "Any other arbitrary data captured by the agent, optionally provided by the user",
            "properties": {
                "db": {
                    "type": ["object", "null"],
                    "description": "An object containing contextual data for database spans",
                    "properties": {
                        "instance": {
                           "type": ["string", "null"],
                           "description": "Database instance name"
                        },
                        "statement": {
                           "type": ["string", "null"],
                           "description": "A database statement (e.g. query) for the given database type"
                        },
                        "type": {
                           "type": ["string", "null"],
                           "description": "Database type. For any SQL database, \"sql\". For others, the lower-case database category, e.g. \"cassandra\", \"hbase\", or \"redis\""
                        },
                        "user": {
                           "type": ["string", "null"],
                           "description": "Username for accessing database"
                        }
                    }
                }
            }
        },
        "duration": {
            "type": "number",
            "description": "Duration of the span in milliseconds"
        },
        "name": {
            "type": "string",
            "description": "Generic designation of a span in the scope of a transaction",
            "maxLength": 1024
        },
        "parent": {
            "type": ["number", "null"],
            "description": "The locally unique ID of the parent of the span."
        },
        "stacktrace": {
            "type": ["array", "null"],
            "description": "List of stack frames with variable attributes (eg: lineno, filename, etc)",
            "items": {
                "$ref": "../stacktrace_frame.json"
            },
            "minItems": 0
        },
        "start": {
            "type": "number",
            "description": "Offset relative to the transaction's timestamp identifying the start of the span, in milliseconds"
        },
        "type": {
            "type": "string",
            "description": "Keyword of specific relevance in the service's domain (eg: 'db.postgresql.query', 'template.erb', etc)",
            "maxLength": 1024
        }
    },
    "dependencies": {
        "parent": {
            "required": ["id"]
        }
    },
    "required": ["duration", "name", "start", "type"]
}

Serviceedit

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "doc/spec/service.json",
    "title": "Service",
    "type": "object",
    "properties": {
        "agent": {
            "description": "Name and version of the Elastic APM agent",
            "type": "object",
            "properties": {
                "name": {
                    "description": "Name of the Elastic APM agent, e.g. \"Python\"",
                    "type": "string",
                    "maxLength": 1024
                },
                "version": {
                    "description": "Version of the Elastic APM agent, e.g.\"1.0.0\"",
                    "type": "string",
                    "maxLength": 1024
                }
            },
            "required": ["name", "version"]
        },
        "framework": {
            "description": "Name and version of the web framework used",
            "type": ["object", "null"],
            "properties": {
                "name": {
                    "type": "string",
                    "maxLength": 1024
                },
                "version": {
                    "type": "string",
                    "maxLength": 1024
                }
            },
            "required": ["name", "version"]
        },
        "language": {
            "description": "Name and version of the programming language used",
            "type": ["object", "null"],
            "properties": {
                "name": {
                    "type": "string",
                    "maxLength": 1024
                },
                "version": {
                    "type": ["string", "null"],
                    "maxLength": 1024
                }
            },
            "required": ["name"]
        },
        "name": {
            "description": "Immutable name of the service emitting this event",
            "type": "string",
            "pattern": "^[a-zA-Z0-9 _-]+$",
            "maxLength": 1024
        },
        "environment": {
            "description": "Environment name of the service, e.g. \"production\" or \"staging\"",
            "type": ["string", "null"],
            "maxLength": 1024
        },
        "runtime": {
            "description": "Name and version of the language runtime running this service",
            "type": ["object", "null"],
            "properties": {
                "name": {
                    "type": "string",
                    "maxLength": 1024
                },
                "version": {
                    "type": "string",
                    "maxLength": 1024
                }
            },
            "required": ["name", "version"]
        },
        "version": {
            "description": "Version of the service emitting this event",
            "type": ["string", "null"],
            "maxLength": 1024
        }
    },
    "required": ["agent", "name"]
}

Systemedit

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "doc/spec/system.json",
    "title": "System",
    "type": ["object", "null"],
    "properties": {
        "architecture": {
            "description": "Architecture of the system the agent is running on.",
            "type": ["string", "null"],
            "maxLength": 1024
        },
        "hostname": {
            "description": "Hostname of the system the agent is running on.",
            "type": ["string", "null"],
            "maxLength": 1024
        },
        "platform": {
            "description": "Name of the system platform the agent is running on.",
            "type": ["string", "null"],
            "maxLength": 1024
        }
    }
}

Contextedit

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "doc/spec/context.json",
    "title": "Context",
    "description": "Any arbitrary contextual information regarding the event, captured by the agent, optionally provided by the user",
    "type": ["object", "null"],
    "properties": {
        "custom": {
            "description": "An arbitrary mapping of additional metadata to store with the event.",
            "type": ["object", "null"],
            "regexProperties": true,
            "patternProperties": {
                "^[^.*\"]*$": {}
            },
            "additionalProperties": false
        },
        "response": {
            "type": ["object", "null"],
            "properties": {
                "finished": {
                    "description": "A boolean indicating whether the response was finished or not",
                    "type": ["boolean", "null"]
                },
                "headers": {
                    "description": "A mapping of HTTP headers of the response object",
                    "type": ["object", "null"],
                    "properties": {
                        "content-type": {
                            "type": ["string", "null"]
                        }
                    }
                },
                "headers_sent": {
                    "type": ["boolean", "null"]
                },
                "status_code": {
                    "description": "The HTTP status code of the response.",
                    "type": ["number", "null"]
                }
            }
        },
        "request": {
            "$ref": "request.json"
        },
        "tags": {
            "type": ["object", "null"],
            "description": "A flat mapping of user-defined tags with string values.",
            "regexProperties": true,
            "patternProperties": {
                "^[^.*\"]*$": {
                    "type": "string",
                    "maxLength": 1024
                }
            },
            "additionalProperties": false
        },
        "user": {
            "$ref": "user.json"
        }
    }
}

Stacktrace Frameedit

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/stacktrace_frame.json",
    "title": "Stacktrace",
    "type": "object",
    "description": "A stacktrace frame, contains various bits (most optional) describing the context of the frame",
    "properties": {
        "abs_path": {
            "description": "The absolute path of the file involved in the stack frame",
            "type": ["string", "null"]
        },
        "colno": {
            "description": "Column number",
            "type": ["number", "null"]
        },
        "context_line": {
            "description": "The line of code part of the stack frame",
            "type": ["string", "null"]
        },
        "filename": {
            "description": "The relative filename of the code involved in the stack frame, used e.g. to do error checksumming",
            "type": "string"
        },
        "function": {
            "description": "The function involved in the stack frame",
            "type": ["string", "null"]
        },
        "library_frame": {
            "description": "A boolean, indicating if this frame is from a library or user code",
            "type": ["boolean", "null"]
        },
        "lineno": {
            "description": "The line number of code part of the stack frame, used e.g. to do error checksumming",
            "type": "number"
        },
        "module": {
            "description": "The module to which frame belongs to",
            "type": ["string", "null"]
        },
        "post_context": {
            "description": "The lines of code after the stack frame",
            "type": ["array", "null"],
            "minItems": 0
        },
        "pre_context": {
            "description": "The lines of code before the stack frame",
             "type": ["array", "null"],
            "minItems": 0
        },
        "vars": {
            "description": "Local variables for this stack frame",
            "type": ["object", "null"],
            "properties": {}
        }
    },
    "required": ["filename", "lineno"]
}

Requestedit

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/http.json",
    "title": "Request",
    "description": "If a log record was generated as a result of a http request, the http interface can be used to collect this information.",
    "type": ["object", "null"],
    "properties": {
        "body": {
            "description": "Data should only contain the request body (not the query string). It can either be a dictionary (for standard HTTP requests) or a raw request body.",
            "type": ["object", "string", "null"]
        },
        "env": {
            "description": "The env variable is a compounded of environment information passed from the webserver.",
            "type": ["object", "null"],
            "properties": {}
        },
        "headers": {
            "description": "Should include any headers sent by the requester. Cookies will be taken by headers if supplied.",
            "type": ["object", "null"],
            "properties": {
                "content-type": {
                    "type": ["string", "null"]
                },
                "cookie": {
                    "description": "Cookies sent with the request. It is expected to have values delimited by semicolons.",
                    "type": ["string", "null"]
                },
                "user-agent": {
                    "type": ["string", "null"]
                }
            }
        },
        "http_version": {
            "description": "HTTP version.",
            "type": ["string", "null"],
            "maxLength": 1024
        },
        "method": {
            "description": "HTTP method.",
            "type": "string",
            "maxLength": 1024
        },
        "socket": {
            "type": ["object", "null"],
            "properties": {
                "encrypted": {
                    "description": "Indicates whether request was sent as SSL/HTTPS request.",
                    "type": ["boolean", "null"]
                },
                "remote_address": {
                    "type": ["string", "null"]
                }
            }
        },
        "url": {
            "description": "A complete Url, with scheme, host and path.",
            "type": "object",
            "properties": {
                "raw": {
                    "type": ["string", "null"],
                    "description": "The raw, unparsed URL of the request, e.g https://example.com:443/search?q=elasticsearch#top.",
                    "maxLength": 1024
                },
                "protocol": {
                    "type": ["string", "null"],
                    "description": "The protocol of the request, e.g. 'https:'.",
                    "maxLength": 1024
                },
                "full": {
                    "type": ["string", "null"],
                    "description": "The full, possibly agent-assembled URL of the request, e.g https://example.com:443/search?q=elasticsearch#top.",
                    "maxLength": 1024
                },
                "hostname": {
                    "type": ["string", "null"],
                    "description": "The hostname of the request, e.g. 'example.com'.",
                    "maxLength": 1024
                },
                "port": {
                    "type": ["string", "null"],
                    "description": "The port of the request, e.g. '443'",
                    "maxLength": 1024
                },
                "pathname": {
                    "type": ["string", "null"],
                    "description": "The path of the request, e.g. '/search'",
                    "maxLength": 1024
                },
                "search": {
                    "description": "The search describes the query string of the request. It is expected to have values delimited by ampersands.",
                    "type": ["string", "null"],
                    "maxLength": 1024
                },
                "hash": {
                    "type": ["string", "null"],
                    "description": "The hash of the request URL, e.g. 'top'",
                    "maxLength": 1024
                }
            }
        },
        "cookies": {
            "description": "A parsed key-value object of cookies",
            "type": ["object", "null"]
        }
    },
    "required": ["url", "method"]
}

Useredit

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "docs/spec/user.json",
    "title": "User",
    "description": "Describes the authenticated User for a request.",
    "type": ["object", "null"],
    "properties": {
        "id": {
            "description": "Identifier of the logged in user, e.g. the primary key of the user",
            "type": ["string", "number", "null"],
            "maxLength": 1024
        },
        "email": {
            "description": "Email of the logged in user",
            "type": ["string", "null"],
            "maxLength": 1024
        },
        "username": {
            "description": "The username of the logged in user",
            "type": ["string", "null"],
            "maxLength": 1024
        }
    }
}

Examplesedit

Send an example request to the APM Server:

curl http://localhost:8200/v1/transactions \
  --header "Content-Type: application/json" \
  --data @docs/data/intake-api/generated/transaction/payload.json

See examples on how a transaction request to the APM Server can look like:

Payload with several Transactionsedit

{
    "service": {
        "name": "1234_service-12a3",
        "version": "5.1.3",
        "environment": "staging",
        "language": {
            "name": "ecmascript",
            "version": "8"
        },
        "runtime": {
            "name": "node",
            "version": "8.0.0"
        },
        "framework": {
            "name": "Express",
            "version": "1.2.3"
        },
        "agent": {
            "name": "elastic-node",
            "version": "3.14.0"
        }
    },
    "process": {
        "pid": 1234,
        "title": "node",
        "argv": [
            "node",
            "server.js"
        ]
    },
    "system": {
        "hostname": "prod1.example.com",
        "architecture": "x64",
        "platform": "darwin"
    },
    "transactions": [
        {
            "id": "945254c5-67a5-417e-8a4e-aa29efcbfb79",
            "name": "GET /api/types",
            "type": "request",
            "duration": 32.592981,
            "result": "success",
            "timestamp": "2017-05-30T18:53:27.154Z",
            "sampled": true,
            "span_count": {
                "dropped": {
                    "total": 2
                }
            },
            "context": {
                "request": {
                    "socket": {
                        "remote_address": "12.53.12.1",
                        "encrypted": true
                    },
                    "http_version": "1.1",
                    "method": "POST",
                    "url": {
                        "protocol": "https:",
                        "full": "https://www.example.com/p/a/t/h?query=string#hash",
                        "hostname": "www.example.com",
                        "port": "8080",
                        "pathname": "/p/a/t/h",
                        "search": "?query=string",
                        "hash": "#hash",
                        "raw": "/p/a/t/h?query=string#hash"
                    },
                    "headers": {
                        "user-agent": "Mozilla Chrome Edge",
                        "content-type": "text/html",
                        "cookie": "c1=v1; c2=v2",
                        "some-other-header": "foo",
                        "array": [
                            "foo",
                            "bar",
                            "baz"
                        ]
                    },
                    "cookies": {
                        "c1": "v1",
                        "c2": "v2"
                    },
                    "env": {
                        "SERVER_SOFTWARE": "nginx",
                        "GATEWAY_INTERFACE": "CGI/1.1"
                    },
                    "body": "Hello World"
                },
                "response": {
                    "status_code": 200,
                    "headers": {
                        "content-type": "application/json"
                    },
                    "headers_sent": true,
                    "finished": true
                },
                "user": {
                    "id": "99",
                    "username": "foo",
                    "email": "foo@example.com"
                },
                "tags": {
                    "organization_uuid": "9f0e9d64-c185-4d21-a6f4-4673ed561ec8"
                },
                "custom": {
                    "my_key": 1,
                    "some_other_value": "foo bar",
                    "and_objects": {
                        "foo": [
                            "bar",
                            "baz"
                        ]
                    }
                }
            },
            "spans": [
                {
                    "id": 0,
                    "parent": null,
                    "name": "SELECT FROM product_types",
                    "type": "db.postgresql.query",
                    "start": 2.83092,
                    "duration": 3.781912,
                    "stacktrace": [
                        {
                            "function": "onread",
                            "abs_path": "net.js",
                            "filename": "net.js",
                            "lineno": 547,
                            "library_frame": true,
                            "vars": {
                              "key": "value"
                            },
                            "module": "some module",
                            "colno": 4,
                            "context_line": "line3",
                            "pre_context": [
                                "  var trans = this.currentTransaction",
                                ""
                            ],
                            "post_context": [
                                "    ins.currentTransaction = prev",
                                "    return result",
                                "}"
                            ]
                        },
                        {
                            "filename": "my2file.js",
                            "lineno": 10
                        }
                    ],
                    "context": {
                        "db": {
                            "instance": "customers",
                            "statement": "SELECT * FROM product_types WHERE user_id=?",
                            "type": "sql",
                            "user": "readonly_user"
                        }
                    }
                },
                {
                    "id": 1,
                    "parent": 0,
                    "name": "GET /api/types",
                    "type": "request",
                    "start": 0,
                    "duration": 32.592981
                },
                {
                    "id": 2,
                    "parent": 1,
                    "name": "GET /api/types",
                    "type": "request",
                    "start": 1.845,
                    "duration": 3.5642981,
                    "stacktrace": [],
                    "context": {}
                },
                {
                    "id": 3,
                    "parent": 2,
                    "name": "GET /api/types",
                    "type": "request",
                    "start": 0,
                    "duration": 13.9802981,
                    "stacktrace": null,
                    "context": null
                }
            ],
            "marks": {
                "navigationTiming": {
                    "appBeforeBootstrap": 608.9300000000001,
                    "navigationStart": -21

                },
                "performance": {}
            }
        },
        {
            "id": "85925e55-b43f-4340-a8e0-df1906ecbf7a",
            "name": "GET /api/types",
            "type": "request",
            "duration": 13.980558,
            "result": "failure",
            "timestamp": "2017-05-30T18:53:42.281Z",
            "spans": [],
            "sampled": true
        },
        {
            "id": "85925e55-b43f-4340-a8e0-df1906ecbf78",
            "name": "GET /api/types",
            "type": "request",
            "duration": 13.980558,
            "result": "200",
            "timestamp": "2017-05-30T18:53:42Z",
            "sampled": false
        },
        {
            "id": "85925e55-b43f-4340-a8e0-df1906ecbfa9",
            "name": "GET /api/types",
            "type": "request",
            "duration": 13.980558,
            "result": "200",
            "timestamp": "2017-05-30T18:53:42.281999Z",
            "sampled": true,
            "span_count": {
                "dropped": {
                    "total": 258
                }
            },
            "spans": [
                {
                    "name": "SELECT FROM product_types",
                    "type": "db.postgresql.query",
                    "start": 2.83092,
                    "duration": 3.781912,
                    "stacktrace": [],
                    "context": {
                        "db": {
                            "instance": "customers",
                            "statement": "SELECT * FROM product_types WHERE user_id=?",
                            "type": "sql",
                            "user": "readonly_user"
                        }
                    }
                }
            ]
        }
    ]
}

Payload with a minimal Transactionedit

{
    "service": {
        "name": "service1",
        "agent": {
            "name": "python",
            "version": "1.0"
        }
    },
    "transactions": [
        {
            "id": "945254c5-67a5-417e-8a4e-aa29efcbfb79",
            "name": "GET /api/types",
            "type": "request",
            "duration": 32.592981,
            "timestamp": "2017-05-09T15:04:05.999999Z"
        }
    ]
}

Payload with a Transaction with a minimal Spanedit

{
    "service": {
        "name": "service1",
        "agent": {
            "name": "python",
            "version": "1.0"
        }
    },
    "transactions": [
        {
            "id": "945254c5-67a5-417e-8a4e-aa29efcbfb79",
            "name": "GET /api/types",
            "type": "request",
            "duration": 32.592981,
            "timestamp": "2017-05-30T18:53:27.154Z",
            "spans": [
                {
                    "name": "GET /api/types",
                    "type": "request",
                    "start": 0,
                    "duration": 32.592981
                }
            ]
        }
    ]
}