POST /v1/logs is the single ingestion endpoint for the Peeng API — it accepts a batch of 1 to 500 structured log entries in one request and is the same endpoint every Peeng SDK method calls under the hood. You can use it directly with any HTTP client if you prefer to stay dependency-free.
A key unique to this batch. Safe to reuse on retries for up to 24 hours — Peeng returns the original response without writing duplicate entries. See Idempotency.
An array of 1 to 500 log entry objects. Every entry in the array is validated; if any entry fails validation the entire request is rejected with a 400 and nothing is written.
The environment that emitted this log — for example production, staging, or development. Use any string you apply consistently across your services so you can filter by environment in the dashboard.
A value between 100 and 599 that models the outcome of the operation this log describes — 200 for a routine success, 500 for an unhandled error, and so on. This is not tied to the HTTP status code of the ingestion request itself.
Any JSON-serializable object containing extra structured context for this log entry — for example request parameters, feature flags, or business identifiers.
The full stack trace text associated with an error. Providing this field enables the Explain with AI feature in the Peeng dashboard, which summarises the root cause and suggests a fix.
A request or trace ID that correlates this log entry with the inbound request that triggered it. Use this to reconstruct a request’s full journey across services.
The time the event occurred, in ISO 8601 format (e.g. 2025-01-15T10:30:00.000Z). If you omit this field, Peeng stamps the entry with the time the request was received. Supply an explicit timestamp when you buffer and flush entries asynchronously.
The number of log entries persisted from this request. A 202 response with accepted equal to the length of the logs array confirms that every entry in the batch was written successfully. There is no partial-success shape — a request either succeeds entirely or fails validation entirely, so accepted will always match the number of entries you submitted on a 202.
{"docsConfig":{"theme":"luma","$schema":"https://mintlify.com/docs.json","name":"Peeng","description":"Documentation for the Peeng AI-powered observability API and SDKs — send logs via HTTP or the JavaScript/TypeScript and Python SDKs.","colors":{"primary":"#7C3AED","light":"#A78BFA","dark":"#5B21B6"},"favicon":"https://mintcdn.com/peeng-technologies/de3JNTiFdAogbDAq/favicon.svg?fit=max\u0026auto=format\u0026n=de3JNTiFdAogbDAq\u0026q=85\u0026s=4c6c63d3d23f74cb9ac0c86ff203d18e","navbar":{"links":[{"href":"https://peeng.dev","label":"Dashboard"}],"primary":{"type":"button","label":"Get started free","href":"https://peeng.dev/register"}},"footer":{"socials":{"x":"https://x.com/peengtech"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"peeng-technologies","hasAudioNarration":false,"actualSubdomain":"peeng-technologies","customDomains":["docs.peeng.dev"],"gitSource":{"type":"github","owner":"mintlify-community","repo":"docs-peeng-technologies-b026d2fa","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"latestBuiltDeploymentHistoryId":"6a6cbad259fa92209ec2daf9","collectionId":"4c8efaca-3f78-4639-93a2-43ae227fa656","liveDeploymentHistoryId":"6a6cbad259fa92209ec2daf9","schemaVersion":"v3"},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6a6cbad259fa92209ec2daf9:success","clientVersion":"0.0.4021","searchFilterCounts":[{"language":"default","tag":"Guides","count":8},{"language":"default","tag":"Get Started","count":3},{"language":"default","tag":"Essentials","count":3},{"language":"default","tag":"API Reference","count":2},{"language":"default","tag":"SDKs","count":2},{"language":"default","tag":"Overview","count":1},{"language":"default","tag":"Logs","count":1}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/logs/ingest","slug":"/api-reference/logs/ingest","pageMetadata":{"title":"POST /v1/logs — Batch Ingest Structured Log Entries","sidebarTitle":"Ingest Logs","description":"Send 1–500 structured log entries in a single batch request. Supports idempotent retries and accepts level, message, metadata, stack traces, and more.","api":"POST https://api.peeng.dev/v1/logs","href":"/api-reference/logs/ingest"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Send 1–500 structured log entries in a single batch request. Supports idempotent retries and accepts level, message, metadata, stack traces, and more.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,..._provideComponents(),...props.components},{Expandable,Heading,ParamField,ResponseField,Table}=_components;if(!Expandable)_missingMdxReference(`Expandable`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!ParamField)_missingMdxReference(`ParamField`,true);if(!ResponseField)_missingMdxReference(`ResponseField`,true);if(!Table)_missingMdxReference(`Table`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[_jsx(_components.code,{children:`POST /v1/logs`}),` is the single ingestion endpoint for the Peeng API — it accepts a batch of 1 to 500 structured log entries in one request and is the same endpoint every Peeng SDK method calls under the hood. You can use it directly with any HTTP client if you prefer to stay dependency-free.`]}),`\n`,_jsx(Heading,{level:`2`,id:`headers`,children:`Headers`}),`\n`,_jsx(ParamField,{header:`x-api-key`,type:`string`,required:true,id:`param-x-api-key`,children:_jsxs(_components.p,{children:[`Your project’s API key. See `,_jsx(_components.a,{href:`/authentication`,children:`Authentication`}),` for how to obtain and manage keys.`]})}),`\n`,_jsx(ParamField,{header:`Idempotency-Key`,type:`string`,id:`param-idempotency-key`,children:_jsxs(_components.p,{children:[`A key unique to this batch. Safe to reuse on retries for up to 24 hours — Peeng returns the original response without writing duplicate entries. See `,_jsx(_components.a,{href:`/essentials/idempotency`,children:`Idempotency`}),`.`]})}),`\n`,_jsx(ParamField,{header:`Content-Type`,type:`string`,required:true,id:`param-content-type`,children:_jsxs(_components.p,{children:[`Must be `,_jsx(_components.code,{children:`application/json`}),`.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`request-body`,children:`Request Body`}),`\n`,_jsxs(ParamField,{body:`logs`,type:`array`,required:true,id:`param-logs`,children:[_jsxs(_components.p,{children:[`An array of 1 to 500 log entry objects. Every entry in the array is validated; if any entry fails validation the entire request is rejected with a `,_jsx(_components.code,{children:`400`}),` and nothing is written.`]}),_jsxs(Expandable,{title:`Log entry fields`,children:[_jsx(ParamField,{body:`level`,type:`string`,required:true,id:`param-level`,children:_jsxs(_components.p,{children:[`Severity level of the log entry. Must be one of `,_jsx(_components.code,{children:`debug`}),`, `,_jsx(_components.code,{children:`info`}),`, `,_jsx(_components.code,{children:`warn`}),`, `,_jsx(_components.code,{children:`error`}),`, or `,_jsx(_components.code,{children:`fatal`}),`.`]})}),_jsx(ParamField,{body:`message`,type:`string`,required:true,id:`param-message`,children:_jsx(_components.p,{children:`The human-readable log message describing the event.`})}),_jsx(ParamField,{body:`environment`,type:`string`,required:true,id:`param-environment`,children:_jsxs(_components.p,{children:[`The environment that emitted this log — for example `,_jsx(_components.code,{children:`production`}),`, `,_jsx(_components.code,{children:`staging`}),`, or `,_jsx(_components.code,{children:`development`}),`. Use any string you apply consistently across your services so you can filter by environment in the dashboard.`]})}),_jsx(ParamField,{body:`statusCode`,type:`integer`,required:true,id:`param-status-code`,children:_jsxs(_components.p,{children:[`A value between `,_jsx(_components.code,{children:`100`}),` and `,_jsx(_components.code,{children:`599`}),` that models the outcome of the operation this log describes — `,_jsx(_components.code,{children:`200`}),` for a routine success, `,_jsx(_components.code,{children:`500`}),` for an unhandled error, and so on. This is not tied to the HTTP status code of the ingestion request itself.`]})}),_jsx(ParamField,{body:`service`,type:`string`,id:`param-service`,children:_jsxs(_components.p,{children:[`The name of the service or process that emitted this log, e.g. `,_jsx(_components.code,{children:`checkout-api`}),`. Use this to group and filter logs by service in the dashboard.`]})}),_jsx(ParamField,{body:`metadata`,type:`object`,id:`param-metadata`,children:_jsx(_components.p,{children:`Any JSON-serializable object containing extra structured context for this log entry — for example request parameters, feature flags, or business identifiers.`})}),_jsx(ParamField,{body:`stackTrace`,type:`string`,id:`param-stack-trace`,children:_jsxs(_components.p,{children:[`The full stack trace text associated with an error. Providing this field enables the `,_jsx(_components.strong,{children:`Explain with AI`}),` feature in the Peeng dashboard, which summarises the root cause and suggests a fix.`]})}),_jsx(ParamField,{body:`hostname`,type:`string`,id:`param-hostname`,children:_jsx(_components.p,{children:`The hostname or instance identifier of the machine that emitted the log. Useful for pinpointing issues on a specific node in a distributed system.`})}),_jsx(ParamField,{body:`requestId`,type:`string`,id:`param-request-id`,children:_jsx(_components.p,{children:`A request or trace ID that correlates this log entry with the inbound request that triggered it. Use this to reconstruct a request’s full journey across services.`})}),_jsx(ParamField,{body:`userId`,type:`string`,id:`param-user-id`,children:_jsx(_components.p,{children:`The identifier of the end user this log pertains to, if applicable. Lets you search and filter logs by user in the dashboard.`})}),_jsx(ParamField,{body:`timestamp`,type:`string`,id:`param-timestamp`,children:_jsxs(_components.p,{children:[`The time the event occurred, in ISO 8601 format (e.g. `,_jsx(_components.code,{children:`2025-01-15T10:30:00.000Z`}),`). If you omit this field, Peeng stamps the entry with the time the request was received. Supply an explicit timestamp when you buffer and flush entries asynchronously.`]})})]})]}),`\n`,`\n`,`\n`,_jsx(Heading,{level:`2`,id:`response-fields`,children:`Response Fields`}),`\n`,_jsxs(_components.p,{children:[`A `,_jsx(_components.code,{children:`202`}),` response body contains a single field confirming how many entries were written.`]}),`\n`,_jsx(ResponseField,{name:`accepted`,type:`integer`,id:`param-accepted`,children:_jsxs(_components.p,{children:[`The number of log entries persisted from this request. A `,_jsx(_components.code,{children:`202`}),` response with `,_jsx(_components.code,{children:`accepted`}),` equal to the length of the `,_jsx(_components.code,{children:`logs`}),` array confirms that every entry in the batch was written successfully. There is no partial-success shape — a request either succeeds entirely or fails validation entirely, so `,_jsx(_components.code,{children:`accepted`}),` will always match the number of entries you submitted on a `,_jsx(_components.code,{children:`202`}),`.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`response-codes`,children:`Response Codes`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Code`}),_jsx(_components.th,{children:`Meaning`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`202`})}),_jsx(_components.td,{children:`Accepted — all entries in the batch were persisted.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`400`})}),_jsx(_components.td,{children:`Validation failed on one or more entries.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`401`})}),_jsx(_components.td,{children:`Missing or invalid API key.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`402`})}),_jsx(_components.td,{children:`Monthly ingestion limit reached for your plan.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`409`})}),_jsxs(_components.td,{children:[`Same `,_jsx(_components.code,{children:`Idempotency-Key`}),` is already being processed.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`429`})}),_jsx(_components.td,{children:`Rate limited.`})]})]})]}),`\n`,_jsxs(_components.p,{children:[`See `,_jsx(_components.a,{href:`/essentials/errors`,children:`Errors`}),` for the full response envelope shape and retry guidance.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"POST /v1/logs — Batch Ingest Structured Log Entries","sidebarTitle":"Ingest Logs","description":"Send 1–500 structured log entries in a single batch request. Supports idempotent retries and accepts level, message, metadata, stack traces, and more.","api":"POST https://api.peeng.dev/v1/logs","href":"/api-reference/logs/ingest"}}},"mdxSourceWithNoJs":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,..._provideComponents(),...props.components},{CodeBlock,Expandable,Heading,ParamField,RequestExample,ResponseExample,ResponseField,Table}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Expandable)_missingMdxReference(`Expandable`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!ParamField)_missingMdxReference(`ParamField`,true);if(!RequestExample)_missingMdxReference(`RequestExample`,true);if(!ResponseExample)_missingMdxReference(`ResponseExample`,true);if(!ResponseField)_missingMdxReference(`ResponseField`,true);if(!Table)_missingMdxReference(`Table`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[_jsx(_components.code,{children:`POST /v1/logs`}),` is the single ingestion endpoint for the Peeng API — it accepts a batch of 1 to 500 structured log entries in one request and is the same endpoint every Peeng SDK method calls under the hood. You can use it directly with any HTTP client if you prefer to stay dependency-free.`]}),`\n`,_jsx(Heading,{level:`2`,id:`headers`,children:`Headers`}),`\n`,_jsx(ParamField,{header:`x-api-key`,type:`string`,required:true,id:`param-x-api-key`,children:_jsxs(_components.p,{children:[`Your project’s API key. See `,_jsx(_components.a,{href:`/authentication`,children:`Authentication`}),` for how to obtain and manage keys.`]})}),`\n`,_jsx(ParamField,{header:`Idempotency-Key`,type:`string`,id:`param-idempotency-key`,children:_jsxs(_components.p,{children:[`A key unique to this batch. Safe to reuse on retries for up to 24 hours — Peeng returns the original response without writing duplicate entries. See `,_jsx(_components.a,{href:`/essentials/idempotency`,children:`Idempotency`}),`.`]})}),`\n`,_jsx(ParamField,{header:`Content-Type`,type:`string`,required:true,id:`param-content-type`,children:_jsxs(_components.p,{children:[`Must be `,_jsx(_components.code,{children:`application/json`}),`.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`request-body`,children:`Request Body`}),`\n`,_jsxs(ParamField,{body:`logs`,type:`array`,required:true,id:`param-logs`,children:[_jsxs(_components.p,{children:[`An array of 1 to 500 log entry objects. Every entry in the array is validated; if any entry fails validation the entire request is rejected with a `,_jsx(_components.code,{children:`400`}),` and nothing is written.`]}),_jsxs(Expandable,{title:`Log entry fields`,children:[_jsx(ParamField,{body:`level`,type:`string`,required:true,id:`param-level`,children:_jsxs(_components.p,{children:[`Severity level of the log entry. Must be one of `,_jsx(_components.code,{children:`debug`}),`, `,_jsx(_components.code,{children:`info`}),`, `,_jsx(_components.code,{children:`warn`}),`, `,_jsx(_components.code,{children:`error`}),`, or `,_jsx(_components.code,{children:`fatal`}),`.`]})}),_jsx(ParamField,{body:`message`,type:`string`,required:true,id:`param-message`,children:_jsx(_components.p,{children:`The human-readable log message describing the event.`})}),_jsx(ParamField,{body:`environment`,type:`string`,required:true,id:`param-environment`,children:_jsxs(_components.p,{children:[`The environment that emitted this log — for example `,_jsx(_components.code,{children:`production`}),`, `,_jsx(_components.code,{children:`staging`}),`, or `,_jsx(_components.code,{children:`development`}),`. Use any string you apply consistently across your services so you can filter by environment in the dashboard.`]})}),_jsx(ParamField,{body:`statusCode`,type:`integer`,required:true,id:`param-status-code`,children:_jsxs(_components.p,{children:[`A value between `,_jsx(_components.code,{children:`100`}),` and `,_jsx(_components.code,{children:`599`}),` that models the outcome of the operation this log describes — `,_jsx(_components.code,{children:`200`}),` for a routine success, `,_jsx(_components.code,{children:`500`}),` for an unhandled error, and so on. This is not tied to the HTTP status code of the ingestion request itself.`]})}),_jsx(ParamField,{body:`service`,type:`string`,id:`param-service`,children:_jsxs(_components.p,{children:[`The name of the service or process that emitted this log, e.g. `,_jsx(_components.code,{children:`checkout-api`}),`. Use this to group and filter logs by service in the dashboard.`]})}),_jsx(ParamField,{body:`metadata`,type:`object`,id:`param-metadata`,children:_jsx(_components.p,{children:`Any JSON-serializable object containing extra structured context for this log entry — for example request parameters, feature flags, or business identifiers.`})}),_jsx(ParamField,{body:`stackTrace`,type:`string`,id:`param-stack-trace`,children:_jsxs(_components.p,{children:[`The full stack trace text associated with an error. Providing this field enables the `,_jsx(_components.strong,{children:`Explain with AI`}),` feature in the Peeng dashboard, which summarises the root cause and suggests a fix.`]})}),_jsx(ParamField,{body:`hostname`,type:`string`,id:`param-hostname`,children:_jsx(_components.p,{children:`The hostname or instance identifier of the machine that emitted the log. Useful for pinpointing issues on a specific node in a distributed system.`})}),_jsx(ParamField,{body:`requestId`,type:`string`,id:`param-request-id`,children:_jsx(_components.p,{children:`A request or trace ID that correlates this log entry with the inbound request that triggered it. Use this to reconstruct a request’s full journey across services.`})}),_jsx(ParamField,{body:`userId`,type:`string`,id:`param-user-id`,children:_jsx(_components.p,{children:`The identifier of the end user this log pertains to, if applicable. Lets you search and filter logs by user in the dashboard.`})}),_jsx(ParamField,{body:`timestamp`,type:`string`,id:`param-timestamp`,children:_jsxs(_components.p,{children:[`The time the event occurred, in ISO 8601 format (e.g. `,_jsx(_components.code,{children:`2025-01-15T10:30:00.000Z`}),`). If you omit this field, Peeng stamps the entry with the time the request was received. Supply an explicit timestamp when you buffer and flush entries asynchronously.`]})})]})]}),`\n`,_jsx(RequestExample,{children:_jsx(CodeBlock,{filename:`cURL`,numberOfLines:`26`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`26`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -X`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` POST`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://api.peeng.dev/v1/logs`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Content-Type: application/json\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"x-api-key: YOUR_API_KEY\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Idempotency-Key: 5b3f9e2a-6c1d-4e8a-9f2b-1a3c5d7e9f0b\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -d`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"logs\": [`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` {`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"level\": \"error\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"message\": \"Payment webhook failed\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"environment\": \"production\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"service\": \"billing\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"statusCode\": 500,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"stackTrace\": \"Error: timeout\\\\n at processPayment (billing.js:42)\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"requestId\": \"req_8f2a1c\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"metadata\": { \"orderId\": \"order_789\", \"provider\": \"stripe\" }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` {`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"level\": \"info\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"message\": \"Order placed\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"environment\": \"production\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"service\": \"checkout\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"statusCode\": 200,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"userId\": \"user_456\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` }'`})}),`\n`]})})})}),`\n`,_jsx(ResponseExample,{children:_jsx(CodeBlock,{filename:`202 Accepted`,numberOfLines:`3`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`3`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"accepted\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`2`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})})}),`\n`,_jsx(Heading,{level:`2`,id:`response-fields`,children:`Response Fields`}),`\n`,_jsxs(_components.p,{children:[`A `,_jsx(_components.code,{children:`202`}),` response body contains a single field confirming how many entries were written.`]}),`\n`,_jsx(ResponseField,{name:`accepted`,type:`integer`,id:`param-accepted`,children:_jsxs(_components.p,{children:[`The number of log entries persisted from this request. A `,_jsx(_components.code,{children:`202`}),` response with `,_jsx(_components.code,{children:`accepted`}),` equal to the length of the `,_jsx(_components.code,{children:`logs`}),` array confirms that every entry in the batch was written successfully. There is no partial-success shape — a request either succeeds entirely or fails validation entirely, so `,_jsx(_components.code,{children:`accepted`}),` will always match the number of entries you submitted on a `,_jsx(_components.code,{children:`202`}),`.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`response-codes`,children:`Response Codes`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Code`}),_jsx(_components.th,{children:`Meaning`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`202`})}),_jsx(_components.td,{children:`Accepted — all entries in the batch were persisted.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`400`})}),_jsx(_components.td,{children:`Validation failed on one or more entries.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`401`})}),_jsx(_components.td,{children:`Missing or invalid API key.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`402`})}),_jsx(_components.td,{children:`Monthly ingestion limit reached for your plan.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`409`})}),_jsxs(_components.td,{children:[`Same `,_jsx(_components.code,{children:`Idempotency-Key`}),` is already being processed.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`429`})}),_jsx(_components.td,{children:`Rate limited.`})]})]})]}),`\n`,_jsxs(_components.p,{children:[`See `,_jsx(_components.a,{href:`/essentials/errors`,children:`Errors`}),` for the full response envelope shape and retry guidance.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"POST /v1/logs — Batch Ingest Structured Log Entries","sidebarTitle":"Ingest Logs","description":"Send 1–500 structured log entries in a single batch request. Supports idempotent retries and accepts level, message, metadata, stack traces, and more.","api":"POST https://api.peeng.dev/v1/logs","href":"/api-reference/logs/ingest"}}}},"mdxExtracts":{"tableOfContents":[{"title":"Headers","slug":"headers","depth":2,"children":[]},{"title":"Request Body","slug":"request-body","depth":2,"children":[]},{"title":"Response Fields","slug":"response-fields","depth":2,"children":[]},{"title":"Response Codes","slug":"response-codes","depth":2,"children":[]}],"codeExamples":{"request":{"type":"RequestExample","children":[{"filename":"cURL","html":"\u003cpre class=\"shiki shiki-themes github-light-default dark-plus\" style=\"background-color:#ffffff;--shiki-dark-bg:#0B0C0E;color:#1f2328;--shiki-dark:#D4D4D4\" language=\"shellscript\">\u003ccode language=\"shellscript\" numberOfLines=\"26\">\u003cspan class=\"line\">\u003cspan style=\"color:#953800;--shiki-dark:#DCDCAA\">curl\u003c/span>\u003cspan style=\"color:#0550AE;--shiki-dark:#569CD6\"> -X\u003c/span>\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> POST\u003c/span>\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> https://api.peeng.dev/v1/logs\u003c/span>\u003cspan style=\"color:#CF222E;--shiki-dark:#D7BA7D\"> \\\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0550AE;--shiki-dark:#569CD6\"> -H\u003c/span>\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"Content-Type: application/json\"\u003c/span>\u003cspan style=\"color:#CF222E;--shiki-dark:#D7BA7D\"> \\\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0550AE;--shiki-dark:#569CD6\"> -H\u003c/span>\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"x-api-key: YOUR_API_KEY\"\u003c/span>\u003cspan style=\"color:#CF222E;--shiki-dark:#D7BA7D\"> \\\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0550AE;--shiki-dark:#569CD6\"> -H\u003c/span>\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"Idempotency-Key: 5b3f9e2a-6c1d-4e8a-9f2b-1a3c5d7e9f0b\"\u003c/span>\u003cspan style=\"color:#CF222E;--shiki-dark:#D7BA7D\"> \\\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0550AE;--shiki-dark:#569CD6\"> -d\u003c/span>\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> '{\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"logs\": [\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> {\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"level\": \"error\",\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"message\": \"Payment webhook failed\",\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"environment\": \"production\",\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"service\": \"billing\",\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"statusCode\": 500,\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"stackTrace\": \"Error: timeout\\n at processPayment (billing.js:42)\",\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"requestId\": \"req_8f2a1c\",\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"metadata\": { \"orderId\": \"order_789\", \"provider\": \"stripe\" }\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> },\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> {\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"level\": \"info\",\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"message\": \"Order placed\",\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"environment\": \"production\",\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"service\": \"checkout\",\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"statusCode\": 200,\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> \"userId\": \"user_456\"\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> }\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> ]\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#0A3069;--shiki-dark:#CE9178\"> }'\u003c/span>\u003c/span>\n\u003c/code>\u003c/pre>"}],"attributes":[]},"response":{"type":"ResponseExample","children":[{"filename":"202 Accepted","html":"\u003cpre class=\"shiki shiki-themes github-light-default dark-plus\" style=\"background-color:#ffffff;--shiki-dark-bg:#0B0C0E;color:#1f2328;--shiki-dark:#D4D4D4\" language=\"json\">\u003ccode language=\"json\" numberOfLines=\"3\">\u003cspan class=\"line\">\u003cspan style=\"color:#1F2328;--shiki-dark:#D4D4D4\">{\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#116329;--shiki-dark:#9CDCFE\"> \"accepted\"\u003c/span>\u003cspan style=\"color:#1F2328;--shiki-dark:#D4D4D4\">: \u003c/span>\u003cspan style=\"color:#0550AE;--shiki-dark:#B5CEA8\">2\u003c/span>\u003c/span>\n\u003cspan class=\"line\">\u003cspan style=\"color:#1F2328;--shiki-dark:#D4D4D4\">}\u003c/span>\u003c/span>\n\u003c/code>\u003c/pre>"}],"attributes":[]}},"endpoint":{"title":"POST /v1/logs — Batch Ingest Structured Log Entries","path":"/v1/logs","servers":[{"url":"https://api.peeng.dev"}],"method":"post","request":{"security":[],"parameters":{"query":{},"header":{"x-api-key":{"schema":[{"type":"string","description":"Your project’s API key. See Authentication for how to obtain and manage keys.","required":true}]},"Idempotency-Key":{"schema":[{"type":"string","description":"A key unique to this batch. Safe to reuse on retries for up to 24 hours — Peeng returns the original response without writing duplicate entries. See Idempotency ."}]},"Content-Type":{"schema":[{"type":"string","description":"Must be `application/json` .","required":true}]}},"cookie":{},"path":{}},"body":{"application/json":{"schemaArray":[{"type":"object","properties":{"logs":[{"type":"array","items":[{"type":"object","properties":{"level":[{"type":"string","description":"Severity level of the log entry. Must be one of `debug` , `info` , `warn` , `error` , or `fatal` .","required":true}],"message":[{"type":"string","description":"The human-readable log message describing the event.","required":true}],"environment":[{"type":"string","description":"The environment that emitted this log — for example `production` , `staging` , or `development` . Use any string you apply consistently across your services so you can filter by environment in the dashboard.","required":true}],"statusCode":[{"type":"integer","description":"A value between `100` and `599` that models the outcome of the operation this log describes — `200` for a routine success, `500` for an unhandled error, and so on. This is not tied to the HTTP status code of the ingestion request itself.","required":true}],"service":[{"type":"string","description":"The name of the service or process that emitted this log, e.g. `checkout-api` . Use this to group and filter logs by service in the dashboard."}],"metadata":[{"type":"object","properties":{},"description":"Any JSON-serializable object containing extra structured context for this log entry — for example request parameters, feature flags, or business identifiers."}],"stackTrace":[{"type":"string","description":"The full stack trace text associated with an error. Providing this field enables the Explain with AI feature in the Peeng dashboard, which summarises the root cause and suggests a fix."}],"hostname":[{"type":"string","description":"The hostname or instance identifier of the machine that emitted the log. Useful for pinpointing issues on a specific node in a distributed system."}],"requestId":[{"type":"string","description":"A request or trace ID that correlates this log entry with the inbound request that triggered it. Use this to reconstruct a request’s full journey across services."}],"userId":[{"type":"string","description":"The identifier of the end user this log pertains to, if applicable. Lets you search and filter logs by user in the dashboard."}],"timestamp":[{"type":"string","description":"The time the event occurred, in ISO 8601 format (e.g. `2025-01-15T10:30:00.000Z` ). If you omit this field, Peeng stamps the entry with the time the request was received. Supply an explicit timestamp when you buffer and flush entries asynchronously."}]}}],"description":"An array of 1 to 500 log entry objects. Every entry in the array is validated; if any entry fails validation the entire request is rejected with a `400` and nothing is written.","required":true}]}}],"examples":{"example":{"value":{"logs":[{"level":"\u003cstring>","message":"\u003cstring>","environment":"\u003cstring>","statusCode":123,"service":"\u003cstring>","metadata":{},"stackTrace":"\u003cstring>","hostname":"\u003cstring>","requestId":"\u003cstring>","userId":"\u003cstring>","timestamp":"\u003cstring>"}]}}}}}},"response":{"200":{"application/json":{"schemaArray":[{"type":"object","properties":{"accepted":[{"type":"integer","description":"The number of log entries persisted from this request. A `202` response with `accepted` equal to the length of the `logs` array confirms that every entry in the batch was written successfully. There is no partial-success shape — a request either succeeds entirely or fails validation entirely, so `accepted` will always match the number of entries you submitted on a `202` ."}]}}],"examples":{"example":{"value":{"accepted":123}}}}}},"deprecated":false}},"jsLinks":[],"subdomain":"peeng-technologies","siteName":"Peeng","title":"POST /v1/logs — Batch Ingest Structured Log Entries - Peeng","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-07-31T15:10:10.570Z","originalFileLocation":"api-reference/logs/ingest.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Send 1–500 structured log entries in a single batch request. Supports idempotent retries and accepts level, message, metadata, stack traces, and more.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Peeng\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/peeng-technologies/gh7lB-sPJa487E9A/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/peeng-technologies/gh7lB-sPJa487E9A/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/peeng-technologies/gh7lB-sPJa487E9A/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/peeng-technologies/gh7lB-sPJa487E9A/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/peeng-technologies/gh7lB-sPJa487E9A/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/peeng-technologies/gh7lB-sPJa487E9A/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/peeng-technologies/gh7lB-sPJa487E9A/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/peeng-technologies/gh7lB-sPJa487E9A/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/peeng-technologies/gh7lB-sPJa487E9A/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"POST /v1/logs — Batch Ingest Structured Log Entries - Peeng\">\u003cmeta data-mint-head property=\"og:description\" content=\"Send 1–500 structured log entries in a single batch request. Supports idempotent retries and accepts level, message, metadata, stack traces, and more.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Peeng\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.peeng.dev/api-reference/logs/ingest\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://peeng-technologies.mintlify.app/_mintlify/api/og/v2?division=Logs\u0026amp;title=POST+%2Fv1%2Flogs+%E2%80%94+Batch+Ingest+Structured+Log+Entries\u0026amp;description=Send+1%E2%80%93500+structured+log+entries+in+a+single+batch+request.+Supports+idempotent+retries+and+accepts+level%2C+message%2C+metadata%2C+stack+traces%2C+and+more.\u0026amp;theme=913ff3c47c90e1d37f4e1ee0\u0026amp;signature=0a5790198a1c167e0b44c450597420a0a81e73b46b06c25b5381846bf0ad64e3\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"POST /v1/logs — Batch Ingest Structured Log Entries - Peeng\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Send 1–500 structured log entries in a single batch request. Supports idempotent retries and accepts level, message, metadata, stack traces, and more.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://peeng-technologies.mintlify.app/_mintlify/api/og/v2?division=Logs\u0026amp;title=POST+%2Fv1%2Flogs+%E2%80%94+Batch+Ingest+Structured+Log+Entries\u0026amp;description=Send+1%E2%80%93500+structured+log+entries+in+a+single+batch+request.+Supports+idempotent+retries+and+accepts+level%2C+message%2C+metadata%2C+stack+traces%2C+and+more.\u0026amp;theme=913ff3c47c90e1d37f4e1ee0\u0026amp;signature=0a5790198a1c167e0b44c450597420a0a81e73b46b06c25b5381846bf0ad64e3\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/peeng-technologies/gh7lB-sPJa487E9A/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Peeng\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#7C3AED\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.peeng.dev/api-reference/logs/ingest\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/logs/ingest.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.peeng.dev/#organization\",\"name\":\"Peeng\",\"url\":\"https://docs.peeng.dev\"},{\"@type\":\"WebSite\",\"@id\":\"https://docs.peeng.dev#website\",\"name\":\"Peeng\",\"url\":\"https://docs.peeng.dev\",\"publisher\":{\"@id\":\"https://docs.peeng.dev/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.peeng.dev/api-reference/logs/ingest#webpage\",\"url\":\"https://docs.peeng.dev/api-reference/logs/ingest\",\"name\":\"POST /v1/logs — Batch Ingest Structured Log Entries\",\"description\":\"Send 1–500 structured log entries in a single batch request. Supports idempotent retries and accepts level, message, metadata, stack traces, and more.\",\"dateModified\":\"2026-07-31T15:10:10.570Z\",\"isPartOf\":{\"@id\":\"https://docs.peeng.dev#website\"},\"breadcrumb\":{\"@id\":\"https://docs.peeng.dev/api-reference/logs/ingest#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.peeng.dev/api-reference/logs/ingest#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Peeng\",\"item\":\"https://docs.peeng.dev\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"POST /v1/logs — Batch Ingest Structured Log Entries\",\"item\":\"https://docs.peeng.dev/api-reference/logs/ingest\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.peeng.dev/api-reference/logs/ingest#apireference\",\"headline\":\"POST /v1/logs — Batch Ingest Structured Log Entries\",\"name\":\"POST /v1/logs — Batch Ingest Structured Log Entries\",\"description\":\"Send 1–500 structured log entries in a single batch request. Supports idempotent retries and accepts level, message, metadata, stack traces, and more.\",\"url\":\"https://docs.peeng.dev/api-reference/logs/ingest\",\"mainEntityOfPage\":{\"@id\":\"https://docs.peeng.dev/api-reference/logs/ingest#webpage\"},\"dateModified\":\"2026-07-31T15:10:10.570Z\",\"publisher\":{\"@id\":\"https://docs.peeng.dev/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.peeng.dev#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Peeng\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Peeng","nav":{"global":null,"tabs":[{"tab":"Guides","pages":[{"title":"Guides","href":"/introduction"}]},{"tab":"API Reference","groups":[{"group":"Overview","pages":[{"title":"Peeng Log Ingestion API — Concepts and Full Reference","sidebarTitle":"Overview","description":"Base URL, authentication, batching limits, ISO 8601 timestamps, idempotency keys, and error conventions for the Peeng log ingestion HTTP API.","href":"/api-reference/introduction"}]},{"group":"Logs","pages":[{"title":"POST /v1/logs — Batch Ingest Structured Log Entries","sidebarTitle":"Ingest Logs","api":"POST https://api.peeng.dev/v1/logs","href":"/api-reference/logs/ingest"}]}]}]},"title":"POST /v1/logs — Batch Ingest Structured Log Entries - Peeng","buildId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","deploymentId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","dynamics":["c2aa737661","b0f84f53ff","2b790eda92"],"chunks":["OpenApiReferenceProvider-26-lDe7V.js","utils-CWQmgYtH.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-4-Aw3rSD.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-C2zjXYA5.js","snippetPresets-DFmpFA7C.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","Page-CT9uE8Ip.js","ApiExamples-FJpQavWq.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-D_GvPF7k.js","shallow-Bs2ZB0NO.js","getApiPlaygroundDisplay-DCcqJJk-.js","CodeSnippet-DzDxawVe.js","CodeSnippets-aUr7fU-7.js","getPastedJson-Y1fKsj_I.js","icon-DI4zTsDr.js","MethodPill-C0nDlmSQ.js","DuplicateIcon-NUXbx2nQ.js","createIcon-BdTHrPAi.js","DynamicMarkdown-CtpgKJwj.js","SectionHeading-B3x35tOt.js","axios-vUo_bRtp.js"]}