---
title: "Create My Service Statement"
method: POST
path: "/marketplace/me/service-statements"
tags: ["Marketplace"]
---

# Create My Service Statement

`POST /marketplace/me/service-statements`

## Request

- Base URL: `https://be.graph8.com/api/v1`
- URL: `https://be.graph8.com/api/v1/marketplace/me/service-statements`
- Auth: HTTP bearer

Open a draft statement for one of your engagements.

THE PERIOD IS SERVER-DERIVED and any you send is ignored: an active
engagement bills the previous complete calendar month, a terminated one
bills its earliest unbilled month. The retainer is PRORATED to the days the
engagement was actually live, and the meeting lines are generated from the
engagement's own rate, so `amount` is the sum of the lines and never a typed
figure. Add commission / bonus / expense / discount lines, then submit.

409 when a statement already exists for that period. 403 on an
agency-managed engagement - the agency authors those.

## Headers

- `Authorization` string, nullable
- `X-Target-Org-Id` string, nullable

## Request body

- StatementCreateRequest: Open a draft statement for one engagement. `period_start` / `period_end` / `amount` are accepted for parity with the app model and IGNORED by it. The billing period is derived server-side (the previous complete calendar month, or a terminated engagement's earliest unbilled month) so nobody can pick a window that mis-prorates the retainer, and the amount is the sum of the statement's line items. They are documented as ignored rather than dropped from the contract, because dropping a field the app model declares is what makes a proxy 500 on a required one.
  - `engagement_id` string, required: The hiring/engagement to bill. Must be your own.
  - `period_start` string, date, nullable: IGNORED - the period is server-derived.
  - `period_end` string, date, nullable: IGNORED - the period is server-derived.
  - `summary` string, nullable
  - `activities` object, nullable
  - `amount` union: IGNORED - derived from the line items.
    - number
    - string
  - `currency` string

## Response `201`

Successful Response

- ApiResponseMarketplacePayload
  - `data` MarketplacePayload, required: One record, or one action result.
  - `pagination` PaginationMeta
    - `page` integer, required: Current page number (1-indexed)
    - `limit` integer, required: Items per page
    - `total` integer, required: Total number of items
    - `has_next` boolean, required: Whether there are more pages
    - `next_cursor` string, nullable: Opaque cursor for the next page; null when there are no more items. Pass it back as the `cursor` query param to fetch the following page without computing page numbers.
    - `total_available` integer, nullable: Search endpoints only: how many records really match, when known. Can be larger than `total`, which is capped at the 10,000 results that can be paged. For company search this is a distinct-company estimate. Null when unknown; absent outside search.
    - `total_is_lower_bound` boolean, nullable: Search endpoints only: true when more records match than `total` shows (the result set is larger than the 10,000 results that can be paged). Absent outside search.
    - `notes` string[], nullable: Search endpoints only: plain-language notes about the result, e.g. that more records match than can be paged, or that a reversed `between` range was put in order.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/graph8/apis/graph8-developer-api.md) · [All operations](https://skmtc.dev/graph8/apis/graph8-developer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/graph8/apis/graph8-developer-api/revisions/2e7cfa0ca921?raw)
