{"openapi":"3.1.0","info":{"title":"Sredify API","version":"v1","description":"Read a company's SR&ED projects, people, assessments, hours and claims, and add recorded time, notes and links. Docs: https://app.sredify.ca/developers/docs"},"servers":[{"url":"https://app.sredify.ca/api/v1"}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"sred_key_...","description":"A company API key (Account, Apps and API). For the company's own scripts."},"oauth2":{"type":"oauth2","description":"For outside apps: authorization code with PKCE (S256). Browser apps send no secret; server apps also send their secret.","flows":{"authorizationCode":{"authorizationUrl":"https://app.sredify.ca/oauth/authorize","tokenUrl":"https://app.sredify.ca/api/oauth/token","refreshUrl":"https://app.sredify.ca/api/oauth/token","scopes":{"company:read":"Company details: Business info, CRA numbers, addresses, SR&ED profile.","people:read":"People: Names, titles, employment type and dates, R&D role, qualifications. No pay.","pay:read":"Pay: Pay type and amount per person, salary amounts in claims. (sensitive, Admin only)","projects:read":"Projects: Projects, their repos, team and Jira projects.","assessments:read":"Assessments: Saved assessments, eligible work, criteria, commit and Jira references.","hours:read":"Hours: Hours per person per project: estimated, recorded, and which counts.","claims:read":"Claims: Contractors, materials, equipment, funding. Salary amounts and totals need Pay too.","evidence:read":"Evidence: Recorded time, notes and links, with where each came from.","hours:write":"Record time: Add, change and remove its own time entries. Never changes estimates.","evidence:write":"Add notes and links: Add, change and remove its own notes and links."}}}}},"schemas":{"Address":{"type":"object","properties":{"line1":{"type":"string"},"line2":{"type":"string"},"city":{"type":"string"},"province":{"type":"string"},"postalCode":{"type":"string"},"country":{"type":"string"}},"required":["line1","line2","city","province","postalCode","country"]},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable code to branch on, for example missing_scope."},"message":{"type":"string","description":"Plain-language explanation."}},"required":["code","message"]}},"required":["error"]},"Page":{"type":"object","properties":{"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= for the next page. null on the last page."}},"required":["nextCursor"]},"Org":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"business":{"type":"object","properties":{"legalName":{"type":"string"},"operatingName":{"type":"string"},"businessNumber":{"type":"string","description":"CRA Business Number (9 digits)."},"programAccount":{"type":"string","description":"CRA program account, for example RC0001."},"structure":{"type":"string","enum":["","corporation","sole-prop","partnership"]},"incorporationDate":{"type":"string","description":"yyyy-mm-dd, or empty."},"jurisdiction":{"type":"string"},"headOffice":{"$ref":"#/components/schemas/Address"},"mailingSameAsHead":{"type":"boolean"},"mailing":{"$ref":"#/components/schemas/Address"},"rdLocations":{"type":"array","items":{"$ref":"#/components/schemas/Address"},"description":"Where the R&D is done."},"phone":{"type":"string"},"email":{"type":"string"},"websiteUrl":{"type":"string"},"documentationUrl":{"type":"string"},"contactName":{"type":"string"},"contactTitle":{"type":"string"},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"},"industry":{"type":"string"},"naics":{"type":"string"},"description":{"type":"string"}},"required":["legalName"],"description":"The company profile."},"sred":{"type":"object","properties":{"ccpc":{"type":["boolean","null"],"description":"Canadian-controlled private corporation. null = not answered."},"fiscalYearEnd":{"type":"string","description":"MM-DD."},"associated":{"type":"boolean","description":"Associated with other corporations."},"associatedNames":{"type":"string"},"taxableIncomePrior":{"type":"string","description":"Prior-year taxable income."},"taxableCapitalPrior":{"type":"string","description":"Prior-year taxable capital."},"claimedBefore":{"type":"boolean"},"lastClaimYear":{"type":"string"},"preparerFirm":{"type":"string"},"preparerName":{"type":"string"},"preparerEmail":{"type":"string"},"governmentFunding":{"type":"boolean"},"fundingNotes":{"type":"string"},"maxHoursPerDay":{"type":"number","description":"Most recorded hours one person can have in a day, across all projects."}},"required":["fiscalYearEnd","maxHoursPerDay"],"description":"SR&ED settings used for the claim."}},"required":["id","name","business","sred"]},"Pay":{"type":"object","properties":{"type":{"type":"string","description":"salary, hourly or contract.","enum":["salary","hourly","contract"]},"amount":{"type":["number","null"],"description":"Yearly salary, hourly rate or contract amount, in dollars."}},"required":["type","amount"]},"Person":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"title":{"type":"string"},"department":{"type":"string"},"employmentType":{"type":"string","enum":["full-time","part-time","contractor"]},"startDate":{"type":["string","null"],"description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"},"endDate":{"type":["string","null"],"description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"},"province":{"type":"string","description":"Two-letter province code."},"rdRole":{"type":"string","description":"Role in the R&D work.","enum":["technical","supervisory","support","none"]},"sredPercent":{"type":["number","null"],"description":"Share of their time on SR&ED, 0 to 100."},"specifiedEmployee":{"type":"boolean","description":"Owns 10% or more of the company (or related to someone who does)."},"armsLength":{"type":"boolean"},"degree":{"type":"string"},"field":{"type":"string"},"yearsExperience":{"type":"string"},"githubAuthor":{"type":["string","null"],"description":"The GitHub contributor this person is linked to."},"jiraAccountId":{"type":["string","null"]},"pay":{"$ref":"#/components/schemas/Pay","description":"Only with the pay:read permission."}},"required":["id","name","email","title","department","employmentType","startDate","endDate","province","rdRole","sredPercent","specifiedEmployee","armsLength","degree","field","yearsExperience","githubAuthor","jiraAccountId"]},"Project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"repos":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"owner/repo"},"language":{"type":["string","null"]}},"required":["key","language"]}},"teamIds":{"type":"array","items":{"type":"string"},"description":"People ticked on the project's Team."},"jiraProjectKeys":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","description","repos","teamIds","jiraProjectKeys","createdAt","updatedAt"]},"EligibleWork":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"criteria":{"type":"array","items":{"type":"string"}},"why":{"type":"string"},"hours":{"type":"number","description":"Hours after any edits made in the app."},"originalHours":{"type":"number","description":"Hours the assessment first found."},"confidence":{"type":"number","description":"How sure the review is that this is eligible, 0 to 1.","minimum":0,"maximum":1},"evidence":{"type":"object","properties":{"window":{"type":"string","description":"When the work happened, for example \"Jan 15 - Mar 02, 2026\"."},"commitShas":{"type":"array","items":{"type":"string"}},"files":{"type":"array","items":{"type":"string"},"description":"Only on GET /assessments/{id}."}},"required":["window","commitShas"]},"jiraKeys":{"type":"array","items":{"type":"string"}}},"required":["id","title","summary","criteria","why","hours","originalHours","confidence","evidence","jiraKeys"]},"Assessment":{"type":"object","properties":{"id":{"type":"string"},"repo":{"type":"string","description":"owner/repo"},"projectIds":{"type":"array","items":{"type":"string"}},"kind":{"type":"string","description":"past = what already happened (from commits). future = planning.","enum":["past","future"]},"title":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"since":{"type":["string","null"],"description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"},"until":{"type":["string","null"],"description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"},"adjusted":{"type":"boolean","description":"Hours were edited in the app."},"summary":{"type":["string","null"]},"eligibleWork":{"type":"array","items":{"$ref":"#/components/schemas/EligibleWork"},"description":"Past assessments only."},"contributors":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"login":{"type":["string","null"]},"commits":{"type":"number"},"researchHours":{"type":["number","null"]}},"required":["name","login","commits","researchHours"]},"description":"Past assessments only."},"angles":{"type":"array","items":{"type":"string"},"description":"Future assessments only."}},"required":["id","repo","projectIds","kind","title","createdAt","since","until","adjusted","summary"]},"HoursRow":{"type":"object","properties":{"projectId":{"type":"string"},"personId":{"type":"string"},"name":{"type":"string"},"onTeam":{"type":"boolean","description":"Ticked on the project's Team."},"estimated":{"type":"number","description":"Estimated hours still counting (estimate minus the days that have recorded time)."},"replacedByRecorded":{"type":"number","description":"Estimated hours replaced by recorded time."},"recorded":{"type":"number","description":"Recorded hours."},"recordedDays":{"type":"number","description":"Days with recorded time."},"total":{"type":"number","description":"What counts: estimated + recorded."},"recordedByDay":{"type":"object","additionalProperties":{"type":"object","properties":{"estimateReplaced":{"type":"number"}},"required":["estimateReplaced"]},"description":"Per recorded day: the estimate it replaced."}},"required":["projectId","personId","name","onTeam","estimated","replacedByRecorded","recorded","recordedDays","total","recordedByDay"]},"Hours":{"type":"object","properties":{"from":{"type":"string","description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"},"to":{"type":"string","description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"},"rule":{"type":"string"},"hours":{"type":"array","items":{"$ref":"#/components/schemas/HoursRow"}}},"required":["from","to","rule","hours"]},"ClaimSalary":{"type":"object","properties":{"personId":{"type":"string"},"name":{"type":"string"},"sredPercent":{"type":"number"},"sharePct":{"type":"number","description":"Share of this person's SR&ED time on this project."},"shareEdited":{"type":"boolean"},"hoursHere":{"type":"number"},"hoursAll":{"type":"number"},"recordedHours":{"type":"number"},"flags":{"type":"array","items":{"type":"string"}},"annualPay":{"type":"number","description":"pay:read only."},"sredPay":{"type":"number","description":"pay:read only."},"claimed":{"type":"number","description":"pay:read only."}},"required":["personId","name","sredPercent","sharePct","shareEdited","hoursHere","hoursAll","recordedHours","flags"]},"Claim":{"type":"object","properties":{"projectId":{"type":"string"},"from":{"type":"string","description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"},"to":{"type":"string","description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"},"overheadMethod":{"type":"string","description":"proxy or traditional."},"salaries":{"type":"array","items":{"$ref":"#/components/schemas/ClaimSalary"}},"contractors":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"personId":{"type":["string","null"]},"paid":{"type":"number"},"armsLength":{"type":"boolean"},"inCanada":{"type":"boolean"},"counts":{"type":"number","description":"Amount that counts toward the claim."},"flag":{"type":["string","null"]}},"required":["name","personId","paid","armsLength","inCanada","counts","flag"]}},"materials":{"type":"array","items":{"type":"object","properties":{},"required":[]}},"equipment":{"type":"array","items":{"type":"object","properties":{},"required":[]}},"funding":{"type":"array","items":{"type":"object","properties":{},"required":[],"description":"Government or other help that reduces the claim."}},"summary":{"type":"object","properties":{"contractors":{"type":"number"},"materials":{"type":"number"},"equipment":{"type":"number"},"funding":{"type":"number"},"salaries":{"type":"number","description":"pay:read only."},"overhead":{"type":"number","description":"pay:read only."},"current":{"type":"number","description":"pay:read only."},"qualified":{"type":"number","description":"pay:read only."}},"required":["contractors","materials","equipment","funding"]},"creditEstimate":{"type":"object","properties":{},"required":[],"description":"pay:read only. Estimated refundable and non-refundable credits."},"note":{"type":"string","description":"Present when pay:read is missing."}},"required":["projectId","from","to","overheadMethod","salaries","contractors","materials","equipment","funding","summary"]},"Source":{"type":"object","properties":{"kind":{"type":"string","description":"Who added it.","enum":["user","apiKey","app"]},"id":{"type":"string"},"label":{"type":"string","description":"Shown in the app, for example \"Acme Timer\"."},"approvedBy":{"type":["string","null"],"description":"For keys and apps: the Admin behind it."}},"required":["kind","id","label","approvedBy"]},"Evidence":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"type":{"type":"string","enum":["time","note","link"]},"date":{"type":"string","description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"},"personId":{"type":["string","null"],"description":"Time entries only."},"hours":{"type":["number","null"],"description":"Time entries only."},"title":{"type":"string","description":"For time: what they worked on."},"body":{"type":["string","null"],"description":"Longer notes."},"url":{"type":["string","null"],"description":"Links only."},"source":{"$ref":"#/components/schemas/Source"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"removed":{"type":["object","null"],"properties":{"at":{"type":"string","format":"date-time"},"by":{"type":"string"},"reason":{"type":"string"}},"required":["at","by","reason"],"description":"Removed items stop counting but stay in history."}},"required":["id","projectId","type","date","title","body","url","source","createdAt","updatedAt","removed"]},"TimeInput":{"type":"object","properties":{"projectId":{"type":"string","description":"The project id (GET /projects)."},"personId":{"type":"string","description":"The person's id. Or send email instead."},"email":{"type":"string","description":"The person's email on the People list."},"date":{"type":"string","description":"The day the work happened. Not in the future.","format":"date","example":"2026-03-14"},"hours":{"type":"number","description":"More than 0, at most 24. Rounded to 0.1.","exclusiveMinimum":0,"maximum":24},"description":{"type":"string","description":"What they worked on (at most 300 characters).","maxLength":300},"notes":{"type":"string","description":"Optional longer notes (at most 5000 characters).","maxLength":5000}},"required":["projectId","date","hours","description"]},"TimePatch":{"type":"object","properties":{"date":{"type":"string","description":"The day the work happened.","format":"date","example":"2026-03-14"},"hours":{"type":"number","description":"More than 0, at most 24.","exclusiveMinimum":0,"maximum":24},"description":{"type":"string","description":"What they worked on.","maxLength":300},"notes":{"type":["string","null"],"description":"Send null or empty to clear.","maxLength":5000}},"required":[]},"NoteInput":{"type":"object","properties":{"projectId":{"type":"string","description":"The project id (GET /projects)."},"type":{"type":"string","enum":["note","link"]},"date":{"type":"string","description":"The day it's about. Not in the future.","format":"date","example":"2026-03-14"},"title":{"type":"string","description":"Short title (at most 300 characters).","maxLength":300},"body":{"type":"string","description":"Optional text (at most 5000 characters).","maxLength":5000},"url":{"type":"string","description":"Links only: a full https:// address."}},"required":["projectId","type","date","title"]},"NotePatch":{"type":"object","properties":{"date":{"type":"string","description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"},"title":{"type":"string","description":"Short title.","maxLength":300},"body":{"type":["string","null"],"description":"Send null or empty to clear.","maxLength":5000},"url":{"type":"string","description":"Links only."}},"required":[]}}},"paths":{"/org":{"get":{"operationId":"org","summary":"The company","description":"Company profile and SR&ED settings.","tags":["org"],"security":[{"apiKey":[]},{"oauth2":["company:read"]}],"x-required-scopes":["company:read"],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Org"},"example":{"id":"cmorg1","name":"Acme Robotics Inc.","business":{"legalName":"Acme Robotics Inc.","operatingName":"Acme Robotics","businessNumber":"123456789","industry":"Robotics","naics":"333249"},"sred":{"ccpc":true,"fiscalYearEnd":"12-31","claimedBefore":false,"maxHoursPerDay":10}}}}},"304":{"description":"Not modified (you sent If-None-Match with the current ETag)."},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/people":{"get":{"operationId":"people","summary":"People","description":"Everyone on the company's People list. Pay is included only with pay:read.\n\nAdd pay:read to get each person's pay type and amount.","tags":["people"],"security":[{"apiKey":[]},{"oauth2":["people:read"]}],"x-required-scopes":["people:read"],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Person"}}},"required":["data"]},"example":{"data":[{"id":"per_rita","name":"Rita Robotics","email":"rita@acme.example","title":"Engineer","department":"R&D","employmentType":"full-time","startDate":"2024-01-08","endDate":null,"province":"ON","rdRole":"technical","sredPercent":80,"specifiedEmployee":false,"armsLength":true,"degree":"BEng","field":"Mechatronics","yearsExperience":"6","githubAuthor":"Rita R","jiraAccountId":null}]}}}},"304":{"description":"Not modified (you sent If-None-Match with the current ETag)."},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/projects":{"get":{"operationId":"projects","summary":"Projects","description":"Every project in the company.","tags":["projects"],"security":[{"apiKey":[]},{"oauth2":["projects:read"]}],"x-required-scopes":["projects:read"],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}},"required":["data"]},"example":{"data":[{"id":"p_robot","name":"Robot arm","description":"","repos":[{"key":"acme/robot","language":"TypeScript"}],"teamIds":["per_rita"],"jiraProjectKeys":["ARM"],"createdAt":"2026-01-04T17:00:00.000Z","updatedAt":"2026-03-01T17:00:00.000Z"}]}}}},"304":{"description":"Not modified (you sent If-None-Match with the current ETag)."},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/projects/{id}":{"get":{"operationId":"project","summary":"One project","description":"A single project.","tags":["projects"],"security":[{"apiKey":[]},{"oauth2":["projects:read"]}],"x-required-scopes":["projects:read"],"parameters":[{"name":"id","in":"path","required":true,"description":"The project id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"304":{"description":"Not modified (you sent If-None-Match with the current ETag)."},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assessments":{"get":{"operationId":"assessments","summary":"Assessments","description":"Saved assessments, newest first. Changed files are left out here; get one assessment for those. Source code is never included.","tags":["assessments"],"security":[{"apiKey":[]},{"oauth2":["assessments:read"]}],"x-required-scopes":["assessments:read"],"parameters":[{"name":"projectId","in":"query","required":false,"description":"Only assessments of this project's repos.","schema":{"type":"string"}},{"name":"repo","in":"query","required":false,"description":"Only this repo (owner/repo).","schema":{"type":"string"}},{"name":"kind","in":"query","required":false,"description":"past or future.","schema":{"type":"string","enum":["past","future"]}},{"name":"limit","in":"query","required":false,"description":"Items per page, 1 to 200 (default 50).","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Assessment"}}},"required":["data"]}]}}}},"304":{"description":"Not modified (you sent If-None-Match with the current ETag)."},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assessments/{id}":{"get":{"operationId":"assessment","summary":"One assessment","description":"A single assessment, including the changed file names for each piece of eligible work.","tags":["assessments"],"security":[{"apiKey":[]},{"oauth2":["assessments:read"]}],"x-required-scopes":["assessments:read"],"parameters":[{"name":"id","in":"path","required":true,"description":"The assessment id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Assessment"}}}},"304":{"description":"Not modified (you sent If-None-Match with the current ETag)."},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/hours":{"get":{"operationId":"hours","summary":"Hours","description":"Hours per person per project: estimated, recorded, and what counts. Recorded time replaces the estimate for that person on that day; it is never added on top.","tags":["hours"],"security":[{"apiKey":[]},{"oauth2":["hours:read"]}],"x-required-scopes":["hours:read"],"parameters":[{"name":"projectId","in":"query","required":false,"description":"Only this project.","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Start day, yyyy-mm-dd. Send with to. Default: the project's claim dates (last fiscal year).","schema":{"type":"string","description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"}},{"name":"to","in":"query","required":false,"description":"End day, yyyy-mm-dd.","schema":{"type":"string","description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Hours"},"example":{"from":"2025-01-01","to":"2025-12-31","rule":"Recorded time replaces the estimate for that person on that day; it is never added on top.","hours":[{"projectId":"p_robot","personId":"per_rita","name":"Rita Robotics","onTeam":true,"estimated":412.5,"replacedByRecorded":6,"recorded":7.5,"recordedDays":1,"total":420,"recordedByDay":{"2025-03-14":{"estimateReplaced":6}}}]}}}},"304":{"description":"Not modified (you sent If-None-Match with the current ETag)."},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"hoursCreate","summary":"Record time","description":"Record time a person worked on a project. It counts in the claim right away, labelled with your key or app.\n\nThe person must be on the company's People list and on the project: ticked on its Team, or linked to a GitHub contributor with commits in its repos.\n\nHours: more than 0 and at most 24. The person's recorded total that day, across all projects, can't go over the company's daily maximum (GET /org: sred.maxHoursPerDay, default 10).\n\nNot in the future. Recorded time replaces that day's estimate for the person.","tags":["hours"],"security":[{"apiKey":[]},{"oauth2":["hours:write"]}],"x-required-scopes":["hours:write"],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any unique string (for example a UUID). Sending the same key again within 24 hours returns the first result instead of adding twice.","schema":{"type":"string"}}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Evidence"},"example":{"id":"ev_mf2k1q_a8c3d1","projectId":"p_robot","type":"time","date":"2026-03-14","personId":"per_rita","hours":7.5,"title":"Grip force tests on prototype 3","body":null,"url":null,"source":{"kind":"app","id":"cmuabc123","label":"Acme Timer","approvedBy":"Ann Admin"},"createdAt":"2026-03-14T23:10:00.000Z","updatedAt":"2026-03-14T23:10:00.000Z","removed":null}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeInput"},"example":{"projectId":"p_robot","email":"rita@acme.example","date":"2026-03-14","hours":7.5,"description":"Grip force tests on prototype 3"}}}}}},"/hours/{id}":{"patch":{"operationId":"hoursUpdate","summary":"Change a time entry","description":"Change a time entry your key or app added. Send only the fields to change. The person can't change: remove the entry and add a new one.\n\nOnly items your own key or app added (403 not_yours otherwise).","tags":["hours"],"security":[{"apiKey":[]},{"oauth2":["hours:write"]}],"x-required-scopes":["hours:write"],"parameters":[{"name":"id","in":"path","required":true,"description":"The time entry id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Evidence"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimePatch"},"example":{"hours":6}}}}},"delete":{"operationId":"hoursDelete","summary":"Remove a time entry","description":"Remove a time entry your key or app added. It stops counting and is kept in history with the reason.","tags":["hours"],"security":[{"apiKey":[]},{"oauth2":["hours:write"]}],"x-required-scopes":["hours:write"],"parameters":[{"name":"id","in":"path","required":true,"description":"The time entry id.","schema":{"type":"string"}},{"name":"reason","in":"query","required":true,"description":"Why it's removed (shown in the app's history).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Evidence"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/claims/{projectId}":{"get":{"operationId":"claim","summary":"A project's claim","description":"The claim numbers for a project, calculated exactly as on the Claim screen.\n\nSalary amounts, totals and the credit estimate need pay:read too. Without it you get hours and shares only, plus a note.","tags":["claims"],"security":[{"apiKey":[]},{"oauth2":["claims:read"]}],"x-required-scopes":["claims:read"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id.","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Start day, yyyy-mm-dd. Send with to. Default: the project's claim dates (last fiscal year).","schema":{"type":"string","description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"}},{"name":"to","in":"query","required":false,"description":"End day, yyyy-mm-dd.","schema":{"type":"string","description":"A day, yyyy-mm-dd.","format":"date","example":"2026-03-14"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Claim"}}}},"304":{"description":"Not modified (you sent If-None-Match with the current ETag)."},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/evidence":{"get":{"operationId":"evidence","summary":"Recorded time, notes and links","description":"Everything added as evidence (in the app, by keys and by apps), oldest change first. Use since= to sync only what changed.","tags":["evidence"],"security":[{"apiKey":[]},{"oauth2":["evidence:read"]}],"x-required-scopes":["evidence:read"],"parameters":[{"name":"projectId","in":"query","required":false,"description":"Only this project.","schema":{"type":"string"}},{"name":"type","in":"query","required":false,"description":"time, note or link.","schema":{"type":"string","enum":["time","note","link"]}},{"name":"since","in":"query","required":false,"description":"Only items changed at or after this ISO date or date-time.","schema":{"type":"string","format":"date-time"}},{"name":"includeRemoved","in":"query","required":false,"description":"true to include removed items.","schema":{"type":"string","enum":["true","false"]}},{"name":"limit","in":"query","required":false,"description":"Items per page, 1 to 200 (default 50).","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Evidence"}}},"required":["data"]}]}}}},"304":{"description":"Not modified (you sent If-None-Match with the current ETag)."},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"evidenceCreate","summary":"Add a note or link","description":"Add a note or a link (a design doc, a test report, a ticket) to a project.\n\nLinks must be full https:// (or http://) addresses.","tags":["evidence"],"security":[{"apiKey":[]},{"oauth2":["evidence:write"]}],"x-required-scopes":["evidence:write"],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any unique string (for example a UUID). Sending the same key again within 24 hours returns the first result instead of adding twice.","schema":{"type":"string"}}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Evidence"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoteInput"},"example":{"projectId":"p_robot","type":"link","date":"2026-03-14","title":"Grip test report","url":"https://docs.acme.example/grip-tests"}}}}}},"/evidence/{id}":{"get":{"operationId":"evidenceOne","summary":"One evidence item","description":"A single item, removed or not.","tags":["evidence"],"security":[{"apiKey":[]},{"oauth2":["evidence:read"]}],"x-required-scopes":["evidence:read"],"parameters":[{"name":"id","in":"path","required":true,"description":"The item id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Evidence"}}}},"304":{"description":"Not modified (you sent If-None-Match with the current ETag)."},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"evidenceUpdate","summary":"Change a note or link","description":"Change an item your key or app added. Time entries need hours:write instead.","tags":["evidence"],"security":[{"apiKey":[]},{"oauth2":["evidence:write"]}],"x-required-scopes":["evidence:write"],"parameters":[{"name":"id","in":"path","required":true,"description":"The item id.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Evidence"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotePatch"},"example":{"title":"Grip test report v2"}}}}},"delete":{"operationId":"evidenceDelete","summary":"Remove a note or link","description":"Remove an item your key or app added. Kept in history with the reason. Time entries need hours:write instead.","tags":["evidence"],"security":[{"apiKey":[]},{"oauth2":["evidence:write"]}],"x-required-scopes":["evidence:write"],"parameters":[{"name":"id","in":"path","required":true,"description":"The item id.","schema":{"type":"string"}},{"name":"reason","in":"query","required":true,"description":"Why it's removed (shown in the app's history).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Evidence"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not signed in or the key/token stopped working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Breaks a rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}