{"openapi":"3.0.3","info":{"title":"AllSquare API","version":"1.0.0","description":"Read and manage groups, balances, expenses, recurring expenses, and settlements. Authenticate with a v1 OAuth token. [Get started](/docs/api/guide)."},"servers":[{"url":"https://allsquare.app"}],"tags":[{"name":"Groups","description":"Create groups and manage membership."},{"name":"Balances","description":"See what you owe and what others owe you."},{"name":"Expenses","description":"Find, create, and manage expenses."},{"name":"Recurring Expenses","description":"Manage scheduled expenses."},{"name":"Settlements","description":"Preview and record settlements."},{"name":"Spend Summary","description":"Explore spending totals."}],"paths":{"/api/v1/groups":{"get":{"operationId":"listGroups","summary":"List groups","description":"List the groups you can access.","tags":["Groups"],"security":[{"OAuth2":["allsquare:api:read"]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"groups":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"defaultCurrency":{"type":"string"}},"required":["id","name","defaultCurrency"],"additionalProperties":false}}},"required":["groups"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}},"post":{"operationId":"createGroup","summary":"Create a group","description":"Create a group and optionally invite its initial members.","tags":["Groups"],"security":[{"OAuth2":["allsquare:api:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for safe retries of a write request.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"currency":{"type":"string","enum":["USD","CAD","EUR","GBP"]},"memberEmails":{"type":"array","items":{"type":"string","format":"email"},"maxItems":20}},"required":["name"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"group":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"defaultCurrency":{"type":"string"}},"required":["id","name","defaultCurrency"],"additionalProperties":false},"membersAdded":{"type":"number"},"membersNotified":{"type":"number"},"invitationsCreated":{"type":"number"},"invitationEmailsSent":{"type":"number"}},"required":["group","membersAdded","membersNotified","invitationsCreated","invitationEmailsSent"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/groups/{groupId}/members":{"get":{"operationId":"listGroupMembers","summary":"List group members","description":"List the current members of a group you can access.","tags":["Groups"],"security":[{"OAuth2":["allsquare:api:read"]}],"parameters":[{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"groupId":{"type":"string"},"currentUserId":{"type":"string"},"members":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string","nullable":true},"isCurrentUser":{"type":"boolean"},"venmoUsername":{"type":"string","nullable":true}},"required":["id","name","email","isCurrentUser","venmoUsername"],"additionalProperties":false}}},"required":["groupId","currentUserId","members"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}},"post":{"operationId":"addGroupMember","summary":"Add a member by email","description":"Add an existing user to a group or invite them by email.","tags":["Groups"],"security":[{"OAuth2":["allsquare:api:write"]}],"parameters":[{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for safe retries of a write request.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","enum":["added","rejoined"]},"groupId":{"type":"string"},"email":{"type":"string"},"userId":{"type":"string"},"emailSent":{"type":"boolean"}},"required":["status","groupId","email","userId","emailSent"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","enum":["invited"]},"groupId":{"type":"string"},"email":{"type":"string"},"expiresAt":{"type":"string"},"emailSent":{"type":"boolean"}},"required":["status","groupId","email","expiresAt","emailSent"],"additionalProperties":false}]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/balances":{"get":{"operationId":"getAllBalances","summary":"Get balances across groups","description":"Get open balances across your groups, separated by currency.","tags":["Balances"],"security":[{"OAuth2":["allsquare:api:read"]}],"parameters":[{"name":"currency","in":"query","required":false,"schema":{"type":"string","enum":["USD","CAD","EUR","GBP"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"currentUserId":{"type":"string"},"groups":{"type":"array","items":{"type":"object","properties":{"groupId":{"type":"string"},"groupName":{"type":"string","nullable":true},"currency":{"type":"string"},"youOwe":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"number"}},"required":["userId","name","amount"],"additionalProperties":false}},"youAreOwed":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"number"}},"required":["userId","name","amount"],"additionalProperties":false}},"net":{"type":"number"}},"required":["groupId","groupName","currency","youOwe","youAreOwed","net"],"additionalProperties":false}},"totalsByCurrency":{"type":"object","additionalProperties":{"type":"object","properties":{"youOwe":{"type":"number"},"youAreOwed":{"type":"number"},"net":{"type":"number"}},"required":["youOwe","youAreOwed","net"],"additionalProperties":false}},"byPerson":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"direction":{"type":"string","enum":["you_owe","owes_you"]}},"required":["userId","name","amount","currency","direction"],"additionalProperties":false}}},"required":["currentUserId","groups","totalsByCurrency","byPerson"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/groups/{groupId}/balances":{"get":{"operationId":"getGroupBalances","summary":"Get group balances","description":"Get open balances for one group. Amounts are formatted strings in the requested currency.","tags":["Balances"],"security":[{"OAuth2":["allsquare:api:read"]}],"parameters":[{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}},{"name":"currency","in":"query","required":false,"schema":{"type":"string","enum":["USD","CAD","EUR","GBP"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"groupId":{"type":"string"},"currency":{"type":"string"},"totalSpent":{"type":"string"},"youOwe":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"string"},"currency":{"type":"string"}},"required":["userId","name","amount","currency"],"additionalProperties":false}},"youAreOwed":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"string"},"currency":{"type":"string"}},"required":["userId","name","amount","currency"],"additionalProperties":false}}},"required":["groupId","currency","totalSpent","youOwe","youAreOwed"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/expenses":{"get":{"operationId":"listExpenses","summary":"List expenses with cursor pagination","description":"Search and filter expenses. Use nextCursor to request the next page, up to 50 items at a time.","tags":["Expenses"],"security":[{"OAuth2":["allsquare:api:read"]}],"parameters":[{"name":"groupId","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d+$"}},{"name":"query","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"from","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"paidById","in":"query","required":false,"schema":{"type":"string","minLength":1}},{"name":"isRecurring","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}},{"name":"isSettled","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"currentUserId":{"type":"string"},"expenses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"date":{"type":"string","nullable":true},"payer":{"type":"object","properties":{"id":{"type":"string","nullable":true},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"splits":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"number","nullable":true},"percentage":{"type":"number","nullable":true},"splitType":{"type":"string"}},"required":["userId","name","amount","percentage","splitType"],"additionalProperties":false}},"isSettled":{"type":"boolean"},"isRecurring":{"type":"boolean"},"groupId":{"type":"string"},"groupName":{"type":"string","nullable":true}},"required":["id","description","amount","currency","date","payer","splits","isSettled","isRecurring","groupId","groupName"],"additionalProperties":false}},"nextCursor":{"type":"string","nullable":true}},"required":["currentUserId","expenses","nextCursor"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/groups/{groupId}/expenses":{"post":{"operationId":"createExpense","summary":"Create an expense","description":"Create an expense in a group and split it among members.","tags":["Expenses"],"security":[{"OAuth2":["allsquare:api:write"]}],"parameters":[{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for safe retries of a write request.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":200},"amount":{"type":"number","exclusiveMinimum":true,"minimum":0},"currency":{"type":"string","enum":["USD","CAD","EUR","GBP"],"default":"USD"},"paidById":{"type":"string","minLength":1},"splitWith":{"type":"array","items":{"type":"string","minLength":1},"default":[]},"splitType":{"type":"string","enum":["amount","percentage","exact"],"default":"amount"},"date":{"type":"string","description":"The user's local calendar date (YYYY-MM-DD). When omitted the server uses today's UTC date."},"percentageSplits":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string","minLength":1},"amount":{"type":"number"}},"required":["userId","amount"],"additionalProperties":false}},{"type":"object","additionalProperties":{"type":"number"}}]},"exactSplits":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string","minLength":1},"amount":{"type":"number"}},"required":["userId","amount"],"additionalProperties":false}},{"type":"object","additionalProperties":{"type":"number"}}]}},"required":["description","amount"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"expense":{"type":"object","properties":{"id":{"type":"string"},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"date":{"type":"string"},"groupId":{"type":"string"}},"required":["id","description","amount","currency","date","groupId"],"additionalProperties":false}},"required":["expense"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/expenses/{expenseId}":{"get":{"operationId":"getExpense","summary":"Get an expense","description":"Get one expense and its split details.","tags":["Expenses"],"security":[{"OAuth2":["allsquare:api:read"]}],"parameters":[{"name":"expenseId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"currentUserId":{"type":"string"},"expense":{"type":"object","properties":{"id":{"type":"string"},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"date":{"type":"string","nullable":true},"payer":{"type":"object","properties":{"id":{"type":"string","nullable":true},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"splits":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"number","nullable":true},"percentage":{"type":"number","nullable":true},"splitType":{"type":"string"}},"required":["userId","name","amount","percentage","splitType"],"additionalProperties":false}},"isSettled":{"type":"boolean"},"isRecurring":{"type":"boolean"},"groupId":{"type":"string"},"groupName":{"type":"string","nullable":true}},"required":["id","description","amount","currency","date","payer","splits","isSettled","isRecurring","groupId","groupName"],"additionalProperties":false}},"required":["currentUserId","expense"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}},"patch":{"operationId":"updateExpense","summary":"Update an expense","description":"Update an expense you are allowed to edit.","tags":["Expenses"],"security":[{"OAuth2":["allsquare:api:write"]}],"parameters":[{"name":"expenseId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for safe retries of a write request.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":200},"amount":{"type":"number","exclusiveMinimum":true,"minimum":0},"currency":{"type":"string","enum":["USD","CAD","EUR","GBP"]},"paidById":{"type":"string","minLength":1},"splitWith":{"type":"array","items":{"type":"string","minLength":1}},"splitType":{"type":"string","enum":["amount","percentage","exact"]},"date":{"type":"string"},"percentageSplits":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string","minLength":1},"amount":{"type":"number"}},"required":["userId","amount"],"additionalProperties":false}},{"type":"object","additionalProperties":{"type":"number"}}]},"exactSplits":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string","minLength":1},"amount":{"type":"number"}},"required":["userId","amount"],"additionalProperties":false}},{"type":"object","additionalProperties":{"type":"number"}}]}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"expense":{"type":"object","properties":{"id":{"type":"string"},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"date":{"type":"string","nullable":true},"payer":{"type":"object","properties":{"id":{"type":"string","nullable":true},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"splits":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"number","nullable":true},"percentage":{"type":"number","nullable":true},"splitType":{"type":"string"}},"required":["userId","name","amount","percentage","splitType"],"additionalProperties":false}},"isSettled":{"type":"boolean"},"isRecurring":{"type":"boolean"},"groupId":{"type":"string"},"groupName":{"type":"string","nullable":true}},"required":["id","description","amount","currency","date","payer","splits","isSettled","isRecurring","groupId","groupName"],"additionalProperties":false}},"required":["expense"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}},"delete":{"operationId":"deleteExpense","summary":"Delete an expense","description":"Delete an expense after explicit confirmation.","tags":["Expenses"],"security":[{"OAuth2":["allsquare:api:write"]}],"parameters":[{"name":"expenseId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for safe retries of a write request.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirmed":{"type":"boolean"},"userIntent":{"type":"string","minLength":1,"maxLength":500}},"required":["confirmed","userIntent"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean","enum":[true]},"expense":{"type":"object","properties":{"id":{"type":"string"},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"groupId":{"type":"string"}},"required":["id","description","amount","currency","groupId"],"additionalProperties":false}},"required":["deleted","expense"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/recurring-expenses":{"get":{"operationId":"listRecurringExpenses","summary":"List recurring expenses","description":"List recurring expense templates, optionally within one group.","tags":["Recurring Expenses"],"security":[{"OAuth2":["allsquare:api:read"]}],"parameters":[{"name":"groupId","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d+$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"currentUserId":{"type":"string"},"recurringExpenses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"groupId":{"type":"string"},"groupName":{"type":"string","nullable":true},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"frequency":{"type":"string"},"schedule":{"type":"string"},"nextOccurrence":{"type":"string"},"lastGeneratedAt":{"type":"string","nullable":true},"isPaused":{"type":"boolean"},"pausedAt":{"type":"string","nullable":true},"payer":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"splitType":{"type":"string"},"splits":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"number","nullable":true},"percentage":{"type":"number","nullable":true}},"required":["userId","name","amount","percentage"],"additionalProperties":false}},"createdById":{"type":"string"},"canEdit":{"type":"boolean"}},"required":["id","groupId","groupName","description","amount","currency","frequency","schedule","nextOccurrence","lastGeneratedAt","isPaused","pausedAt","payer","splitType","splits","createdById","canEdit"],"additionalProperties":false}}},"required":["currentUserId","recurringExpenses"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/groups/{groupId}/recurring-expenses":{"post":{"operationId":"createRecurringExpense","summary":"Create a recurring expense","description":"Create a recurring expense template for a group.","tags":["Recurring Expenses"],"security":[{"OAuth2":["allsquare:api:write"]}],"parameters":[{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for safe retries of a write request.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":200},"amount":{"type":"number","exclusiveMinimum":true,"minimum":0},"currency":{"type":"string","enum":["USD","CAD","EUR","GBP"],"default":"USD"},"paidById":{"type":"string","minLength":1},"splitWith":{"type":"array","items":{"type":"string","minLength":1},"default":[]},"splitType":{"type":"string","enum":["amount","percentage","exact"],"default":"amount"},"date":{"type":"string","description":"The user's local calendar date (YYYY-MM-DD). When omitted the server uses today's UTC date."},"percentageSplits":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string","minLength":1},"amount":{"type":"number"}},"required":["userId","amount"],"additionalProperties":false}},{"type":"object","additionalProperties":{"type":"number"}}]},"exactSplits":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string","minLength":1},"amount":{"type":"number"}},"required":["userId","amount"],"additionalProperties":false}},{"type":"object","additionalProperties":{"type":"number"}}]},"frequency":{"type":"string","enum":["weekly","biweekly","monthly","yearly"]},"startDate":{"type":"string","description":"First scheduled date as the user's local calendar date (YYYY-MM-DD). When omitted the server uses today's UTC date."}},"required":["description","amount","frequency"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"recurringExpense":{"type":"object","properties":{"id":{"type":"string"},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"frequency":{"type":"string"},"nextOccurrence":{"type":"string"},"groupId":{"type":"string"},"immediateExpenseCreated":{"type":"boolean"},"immediateExpenseId":{"type":"string","nullable":true}},"required":["id","description","amount","currency","frequency","nextOccurrence","groupId","immediateExpenseCreated"],"additionalProperties":false}},"required":["recurringExpense"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/recurring-expenses/{recurringExpenseId}":{"get":{"operationId":"getRecurringExpense","summary":"Get a recurring expense","description":"Get one recurring expense template and its schedule.","tags":["Recurring Expenses"],"security":[{"OAuth2":["allsquare:api:read"]}],"parameters":[{"name":"recurringExpenseId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"currentUserId":{"type":"string"},"recurringExpense":{"type":"object","properties":{"id":{"type":"string"},"groupId":{"type":"string"},"groupName":{"type":"string","nullable":true},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"frequency":{"type":"string"},"schedule":{"type":"string"},"nextOccurrence":{"type":"string"},"lastGeneratedAt":{"type":"string","nullable":true},"isPaused":{"type":"boolean"},"pausedAt":{"type":"string","nullable":true},"payer":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"splitType":{"type":"string"},"splits":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"number","nullable":true},"percentage":{"type":"number","nullable":true}},"required":["userId","name","amount","percentage"],"additionalProperties":false}},"createdById":{"type":"string"},"canEdit":{"type":"boolean"}},"required":["id","groupId","groupName","description","amount","currency","frequency","schedule","nextOccurrence","lastGeneratedAt","isPaused","pausedAt","payer","splitType","splits","createdById","canEdit"],"additionalProperties":false}},"required":["currentUserId","recurringExpense"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}},"patch":{"operationId":"updateRecurringExpense","summary":"Update a recurring expense","description":"Update a recurring expense template you are allowed to edit.","tags":["Recurring Expenses"],"security":[{"OAuth2":["allsquare:api:write"]}],"parameters":[{"name":"recurringExpenseId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for safe retries of a write request.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":200},"amount":{"type":"number","exclusiveMinimum":true,"minimum":0},"paidById":{"type":"string","minLength":1},"splitWith":{"type":"array","items":{"type":"string","minLength":1}},"splitType":{"type":"string","enum":["amount","percentage","exact"]},"frequency":{"type":"string","enum":["weekly","biweekly","monthly","yearly"]},"percentageSplits":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string","minLength":1},"amount":{"type":"number"}},"required":["userId","amount"],"additionalProperties":false}},{"type":"object","additionalProperties":{"type":"number"}}]},"exactSplits":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string","minLength":1},"amount":{"type":"number"}},"required":["userId","amount"],"additionalProperties":false}},{"type":"object","additionalProperties":{"type":"number"}}]}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"recurringExpense":{"type":"object","properties":{"id":{"type":"string"},"groupId":{"type":"string"},"groupName":{"type":"string","nullable":true},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"frequency":{"type":"string"},"schedule":{"type":"string"},"nextOccurrence":{"type":"string"},"lastGeneratedAt":{"type":"string","nullable":true},"isPaused":{"type":"boolean"},"pausedAt":{"type":"string","nullable":true},"payer":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"splitType":{"type":"string"},"splits":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"number","nullable":true},"percentage":{"type":"number","nullable":true}},"required":["userId","name","amount","percentage"],"additionalProperties":false}},"createdById":{"type":"string"},"canEdit":{"type":"boolean"}},"required":["id","groupId","groupName","description","amount","currency","frequency","schedule","nextOccurrence","lastGeneratedAt","isPaused","pausedAt","payer","splitType","splits","createdById","canEdit"],"additionalProperties":false}},"required":["recurringExpense"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}},"delete":{"operationId":"deleteRecurringExpense","summary":"Delete a recurring expense","description":"Delete a recurring expense template after explicit confirmation.","tags":["Recurring Expenses"],"security":[{"OAuth2":["allsquare:api:write"]}],"parameters":[{"name":"recurringExpenseId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for safe retries of a write request.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirmed":{"type":"boolean"},"userIntent":{"type":"string","minLength":1,"maxLength":500}},"required":["confirmed","userIntent"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean","enum":[true]},"recurringExpense":{"type":"object","properties":{"id":{"type":"string"},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"frequency":{"type":"string"},"groupId":{"type":"string"}},"required":["id","description","amount","currency","frequency","groupId"],"additionalProperties":false}},"required":["deleted","recurringExpense"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/recurring-expenses/{recurringExpenseId}/pause":{"patch":{"operationId":"setRecurringExpensePaused","summary":"Pause or resume a recurring expense","description":"Pause or resume future generation from a recurring expense template.","tags":["Recurring Expenses"],"security":[{"OAuth2":["allsquare:api:write"]}],"parameters":[{"name":"recurringExpenseId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for safe retries of a write request.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"paused":{"type":"boolean"}},"required":["paused"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"recurringExpense":{"type":"object","properties":{"id":{"type":"string"},"groupId":{"type":"string"},"groupName":{"type":"string","nullable":true},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"frequency":{"type":"string"},"schedule":{"type":"string"},"nextOccurrence":{"type":"string"},"lastGeneratedAt":{"type":"string","nullable":true},"isPaused":{"type":"boolean"},"pausedAt":{"type":"string","nullable":true},"payer":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"splitType":{"type":"string"},"splits":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"number","nullable":true},"percentage":{"type":"number","nullable":true}},"required":["userId","name","amount","percentage"],"additionalProperties":false}},"createdById":{"type":"string"},"canEdit":{"type":"boolean"}},"required":["id","groupId","groupName","description","amount","currency","frequency","schedule","nextOccurrence","lastGeneratedAt","isPaused","pausedAt","payer","splitType","splits","createdById","canEdit"],"additionalProperties":false}},"required":["recurringExpense"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/settlements":{"get":{"operationId":"listSettlements","summary":"List settlements","description":"List recorded settlements, optionally within one group.","tags":["Settlements"],"security":[{"OAuth2":["allsquare:api:read"]}],"parameters":[{"name":"groupId","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d+$"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"currentUserId":{"type":"string"},"settlements":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"groupId":{"type":"string"},"groupName":{"type":"string","nullable":true},"settledBy":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"settledAt":{"type":"string","nullable":true},"expenseCount":{"type":"number"},"totalsByCurrency":{"type":"object","additionalProperties":{"type":"number"}},"expenses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"description":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"date":{"type":"string","nullable":true},"payerId":{"type":"string","nullable":true}},"required":["id","description","amount","currency","date","payerId"],"additionalProperties":false}}},"required":["id","groupId","groupName","settledBy","settledAt","expenseCount","totalsByCurrency","expenses"],"additionalProperties":false}}},"required":["currentUserId","settlements"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/groups/{groupId}/settlements/preview":{"post":{"operationId":"previewSettlement","summary":"Preview a settlement","description":"Calculate who should pay whom before settling; this does not change any expenses.","tags":["Settlements"],"security":[{"OAuth2":["allsquare:api:read"]}],"parameters":[{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expenseIds":{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"}]},"minItems":1,"maxItems":100},"currency":{"type":"string","enum":["USD","CAD","EUR","GBP"]}},"required":["expenseIds"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"groupId":{"type":"string"},"currency":{"type":"string"},"expenseIds":{"type":"array","items":{"type":"string"}},"payments":{"type":"array","items":{"type":"object","properties":{"direction":{"type":"string","enum":["pay","request"]},"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"string"},"currency":{"type":"string"},"venmoUsername":{"type":"string","nullable":true},"venmoWebUrl":{"type":"string","nullable":true},"venmoProfileUrl":{"type":"string","nullable":true},"venmoMarkdownLink":{"type":"string","nullable":true},"displayText":{"type":"string"},"note":{"type":"string"}},"required":["direction","userId","name","amount","currency","venmoUsername","venmoWebUrl","venmoProfileUrl","venmoMarkdownLink","displayText","note"],"additionalProperties":false}}},"required":["groupId","currency","expenseIds","payments"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/groups/{groupId}/settlements":{"post":{"operationId":"settleExpenses","summary":"Settle expenses","description":"Mark selected expenses as settled after explicit confirmation. This does not transfer money.","tags":["Settlements"],"security":[{"OAuth2":["allsquare:api:write"]}],"parameters":[{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for safe retries of a write request.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expenseIds":{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"}]},"minItems":1,"maxItems":100},"currency":{"type":"string","enum":["USD","CAD","EUR","GBP"]},"confirmed":{"type":"boolean"},"userIntent":{"type":"string","minLength":1,"maxLength":500}},"required":["expenseIds","confirmed","userIntent"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"settlement":{"type":"object","properties":{"id":{"type":"string"},"groupId":{"type":"string"},"settledBy":{"type":"string"},"settledAt":{"type":"string","nullable":true},"expenseIds":{"type":"array","items":{"type":"string"}}},"required":["id","groupId","settledBy","settledAt","expenseIds"],"additionalProperties":false},"payments":{"type":"array","items":{"type":"object","properties":{"direction":{"type":"string","enum":["pay","request"]},"userId":{"type":"string"},"name":{"type":"string"},"amount":{"type":"string"},"currency":{"type":"string"},"venmoUsername":{"type":"string","nullable":true},"venmoWebUrl":{"type":"string","nullable":true},"venmoProfileUrl":{"type":"string","nullable":true},"venmoMarkdownLink":{"type":"string","nullable":true},"displayText":{"type":"string"},"note":{"type":"string"}},"required":["direction","userId","name","amount","currency","venmoUsername","venmoWebUrl","venmoProfileUrl","venmoMarkdownLink","displayText","note"],"additionalProperties":false}}},"required":["settlement","payments"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}},"/api/v1/spend-summary":{"get":{"operationId":"getSpendSummary","summary":"Get spend summary","description":"Summarize spending by person, month, or description using the supplied filters.","tags":["Spend Summary"],"security":[{"OAuth2":["allsquare:api:read"]}],"parameters":[{"name":"groupId","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d+$"}},{"name":"from","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"query","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"currency","in":"query","required":false,"schema":{"type":"string","enum":["USD","CAD","EUR","GBP"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"currentUserId":{"type":"string"},"currency":{"type":"string"},"groupId":{"type":"string","nullable":true},"from":{"type":"string","nullable":true},"to":{"type":"string","nullable":true},"query":{"type":"string","nullable":true},"expenseCount":{"type":"number"},"totalSpent":{"type":"number"},"yourPaid":{"type":"number"},"yourShare":{"type":"number"},"byPerson":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"name":{"type":"string"},"paid":{"type":"number"},"share":{"type":"number"}},"required":["userId","name","paid","share"],"additionalProperties":false}},"byMonth":{"type":"array","items":{"type":"object","properties":{"month":{"type":"string"},"total":{"type":"number"},"count":{"type":"number"}},"required":["month","total","count"],"additionalProperties":false}},"byDescription":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string"},"total":{"type":"number"},"count":{"type":"number"}},"required":["description","total","count"],"additionalProperties":false}},"byGroup":{"type":"array","items":{"type":"object","properties":{"groupId":{"type":"string"},"groupName":{"type":"string","nullable":true},"total":{"type":"number"},"count":{"type":"number"}},"required":["groupId","groupName","total","count"],"additionalProperties":false}}},"required":["currentUserId","currency","groupId","from","to","query","expenseCount","totalSpent","yourPaid","yourShare","byPerson","byMonth","byDescription","byGroup"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ValidationError"]},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Invalid request","code":"ValidationError","fields":{"body":"Required"}}}}},"401":{"description":"Missing or invalid token, including wrong audience","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UnauthorizedError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Authentication required","code":"UnauthorizedError"}}}},"403":{"description":"Missing scope or resource permission","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ForbiddenError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Permission denied","code":"ForbiddenError"}}}},"404":{"description":"Resource not found or v1 API disabled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["NotFoundError","FeatureDisabled"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Resource not found","code":"NotFoundError"}}}},"409":{"description":"Conflict or idempotency-key reuse with different input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["ConflictError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Request conflicts with current state","code":"ConflictError"}}}},"429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Seconds until retry is allowed","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["RateLimitedError","RATE_LIMITED"]},"route":{"type":"string"},"retryAfterSeconds":{"type":"number"}},"required":["error","code","retryAfterSeconds"],"additionalProperties":false},"example":{"error":"Rate limit exceeded","code":"RATE_LIMITED","route":"/groups","retryAfterSeconds":60}}}},"502":{"description":"Upstream dependency unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["UpstreamError"]}},"required":["error","code"],"additionalProperties":false},"example":{"error":"Service temporarily unavailable","code":"UpstreamError"}}}}}}}},"components":{"securitySchemes":{"OAuth2":{"type":"oauth2","x-default-scopes":["allsquare:api:read"],"flows":{"authorizationCode":{"authorizationUrl":"https://allsquare.app/api/oauth/authorize","tokenUrl":"https://allsquare.app/api/oauth/token","x-usePkce":"SHA-256","x-scalar-credentials-location":"body","x-scalar-redirect-uri":"https://allsquare.app/docs/api","x-scalar-security-query":{"resource":"https://allsquare.app/api/v1"},"x-scalar-security-body":{"resource":"https://allsquare.app/api/v1"},"scopes":{"allsquare:api:read":"Read AllSquare data","allsquare:api:write":"Change AllSquare data"}}}}}},"x-oauth-resource":"https://allsquare.app/api/v1"}