{"slug":"api","title":"Read API","summary":"Every endpoint Roiva's read API serves: what each one answers, the parameters it takes, and every field it returns.","section":"Reference","url":"https://roiva-staging.com/docs/reference/api","generated":"Generated from what Roiva ships, on every deploy.","license":"https://roiva-staging.com/terms","tables":[{"title":"GET /api/v1/roi","intro":"Approved value, total cost, net value and the ratio between them, over a reporting window. The same computation the ROI dashboard reads, so the two cannot disagree.","columns":["Parameter","Type","What it means"],"rows":[{"Parameter":"window","Type":"string\noptional","What it means":"The reporting window. Defaults to all. An unrecognized value is refused rather than answered for another period. One of: 1yr, 3yr, 5yr, all."},{"Parameter":"initiative_id","Type":"integer\noptional","What it means":"Narrow the figures to one initiative in this account. An id this account cannot see answers 404."}]},{"intro":"What it answers with.","columns":["Field","Type","What it is"],"rows":[{"Field":"scope","Type":"object\nalways present","What it is":"What these figures cover."},{"Field":"scope.type","Type":"string","What it is":"Whether these figures cover the whole portfolio or one initiative. One of: portfolio, initiative."},{"Field":"scope.id","Type":"integer","What it is":"The initiative's id, when the scope is an initiative."},{"Field":"scope.title","Type":"string","What it is":"The initiative's title, when the scope is an initiative."},{"Field":"period","Type":"object\nalways present","What it is":"The stretch of time they cover."},{"Field":"period.window","Type":"string","What it is":"The reporting window these figures cover."},{"Field":"period.label","Type":"string","What it is":"How the app names that window to a reader."},{"Field":"period.from","Type":"string","What it is":"First day covered, when the window resolves to explicit dates."},{"Field":"period.through","Type":"string","What it is":"Last day covered, when the window resolves to explicit dates."},{"Field":"currency","Type":"string\nalways present","What it is":"ISO 4217 code every amount below is in."},{"Field":"approved_value_cents","Type":"integer\nalways present","What it is":"Value that has been approved, in cents. Unapproved entries do not count."},{"Field":"total_cost_cents","Type":"integer\nalways present","What it is":"Everything the initiatives in scope have cost, in cents."},{"Field":"net_value_cents","Type":"integer\nalways present","What it is":"Approved value minus total cost, in cents."},{"Field":"roi","Type":"number\nmay be null","What it is":"Net value divided by total cost. Null when there is no cost to divide by, which is not the same as zero."},{"Field":"cost","Type":"object\nalways present","What it is":"total_cost_cents split into its one-time and running halves."},{"Field":"cost.capex_cents","Type":"integer","What it is":"The one-time part of total cost, in cents."},{"Field":"cost.opex_cents","Type":"integer","What it is":"The running part of total cost, in cents."}]},{"title":"GET /api/v1/initiatives","intro":"Ordered oldest change first, so a caller can walk forward from where they stopped. Sample initiatives are left out unless asked for.","columns":["Parameter","Type","What it means"],"rows":[{"Parameter":"limit","Type":"integer\noptional · default 100","What it means":"Rows per page, up to 500."},{"Parameter":"cursor","Type":"string\noptional","What it means":"The next_cursor from the previous page. Opaque: its shape is not part of the contract."},{"Parameter":"updated_since","Type":"string\noptional","What it means":"Only rows changed at or after this moment, which is what makes a repeat pull cheap. At or after, not after, so a caller passing back the last updated_at they saw cannot miss a row saved in the same millisecond."},{"Parameter":"include_sample","Type":"boolean\noptional · default false","What it means":"Include provisioned demo initiatives, which are left out by default. A warehouse that ingests them reports figures nobody spent."}]},{"intro":"What a row carries.","columns":["Field","Type","What it is"],"rows":[{"Field":"id","Type":"integer\nalways present","What it is":null},{"Field":"title","Type":"string\nalways present","What it is":null},{"Field":"description","Type":"string\nmay be null","What it is":null},{"Field":"hypothesis","Type":"string\nmay be null","What it is":null},{"Field":"stage","Type":"string\nalways present","What it is":"Where it is in its lifecycle. One of: identified, reviewing, implementing, live, paused, completed, rejected, dismissed."},{"Field":"is_sample","Type":"boolean\nalways present","What it is":"Provisioned demo data. Left out of lists unless include_sample=true, because a warehouse that ingests it reports figures nobody spent."},{"Field":"category","Type":"string\nmay be null","What it is":null},{"Field":"priority","Type":"integer\nmay be null","What it is":"Lower is higher priority."},{"Field":"source","Type":"string\nmay be null","What it is":"How the initiative came to exist."},{"Field":"business_unit","Type":"string\nmay be null","What it is":null},{"Field":"department","Type":"string\nmay be null","What it is":null},{"Field":"gl_dimension_value","Type":"string\nmay be null","What it is":null},{"Field":"owner","Type":"object\nmay be null","What it is":"Who, inside this account. Names, never email addresses."},{"Field":"owner.id","Type":"integer","What it is":null},{"Field":"owner.name","Type":"string","What it is":null},{"Field":"confidence_score","Type":"number\nmay be null","What it is":null},{"Field":"roi_time_horizon_years","Type":"integer\nmay be null","What it is":null},{"Field":"currency","Type":"string\nmay be null","What it is":null},{"Field":"expected_capex_cents","Type":"integer\nmay be null","What it is":"Amount in cents, in the currency beside it."},{"Field":"expected_opex_cents","Type":"integer\nmay be null","What it is":"Amount in cents, in the currency beside it."},{"Field":"expected_cost_savings_cents","Type":"integer\nmay be null","What it is":"Amount in cents, in the currency beside it."},{"Field":"expected_revenue_uplift_cents","Type":"integer\nmay be null","What it is":"Amount in cents, in the currency beside it."},{"Field":"started_at","Type":"string\nmay be null","What it is":null},{"Field":"went_live_at","Type":"string\nmay be null","What it is":null},{"Field":"approved_at","Type":"string\nmay be null","What it is":null},{"Field":"closed_at","Type":"string\nmay be null","What it is":null},{"Field":"submitted_for_review_at","Type":"string\nmay be null","What it is":null},{"Field":"created_at","Type":"string\nalways present","What it is":"When the row was first written."},{"Field":"updated_at","Type":"string\nalways present","What it is":"When it last changed. This is what the list is ordered by, what a cursor points into, and what updated_since compares against."}]},{"title":"GET /api/v1/cost_entries","intro":"What the account has spent, one row per entry, whoever or whatever recorded it. Ordered oldest change first.","columns":["Parameter","Type","What it means"],"rows":[{"Parameter":"limit","Type":"integer\noptional · default 100","What it means":"Rows per page, up to 500."},{"Parameter":"cursor","Type":"string\noptional","What it means":"The next_cursor from the previous page. Opaque: its shape is not part of the contract."},{"Parameter":"updated_since","Type":"string\noptional","What it means":"Only rows changed at or after this moment, which is what makes a repeat pull cheap. At or after, not after, so a caller passing back the last updated_at they saw cannot miss a row saved in the same millisecond."},{"Parameter":"initiative_id","Type":"integer\noptional","What it means":"Only rows belonging to one initiative in this account."},{"Parameter":"period_from","Type":"string\noptional","What it means":"The start of the window. Entries are matched on where their period begins, which is how Roiva's own reports slice a period: an entry belongs to the period it starts in, so a twelve-month entry beginning in January is in Q1 and in no other quarter. Asking for a quarter therefore returns the rows the dashboard counted for it. Either bound may be given on its own."},{"Parameter":"period_to","Type":"string\noptional","What it means":"The end of the window, matched the same way — see period_from."}]},{"intro":"What a row carries.","columns":["Field","Type","What it is"],"rows":[{"Field":"id","Type":"integer\nalways present","What it is":null},{"Field":"initiative_id","Type":"integer\nalways present","What it is":null},{"Field":"amount_cents","Type":"integer\nmay be null","What it is":"Amount in cents, in the currency beside it."},{"Field":"currency","Type":"string\nmay be null","What it is":null},{"Field":"cost_type","Type":"string\nmay be null","What it is":"Software, tokens, implementation, infrastructure and so on."},{"Field":"cost_category","Type":"string\nalways present","What it is":"Whether it is one-time or running. Follows from the type unless somebody changed it. One of: capex, opex."},{"Field":"period_start","Type":"string\nmay be null","What it is":null},{"Field":"period_end","Type":"string\nmay be null","What it is":null},{"Field":"vendor_id","Type":"integer\nmay be null","What it is":"The vendor this is spend with, and the field to group spend by — it is what Roiva's own Vendors page groups on. Resolved from vendor_name when the entry is written, so the two usually agree; they come apart when two vendors are merged, because that repoints vendor_id on the existing entries and leaves their names alone. One vendor's rows can then carry several names, and grouping on the name splits its spend. Null where no name was given, which Roiva reports apart rather than against a vendor."},{"Field":"vendor_name","Type":"string\nmay be null","What it is":"The name as it was recorded, which is free text: an abbreviation, a product name, or a spelling the vendor has since been merged out of."},{"Field":"description","Type":"string\nmay be null","What it is":null},{"Field":"notes","Type":"string\nmay be null","What it is":null},{"Field":"is_estimated","Type":"boolean","What it is":null},{"Field":"locked","Type":"boolean","What it is":"In a closed accounting period, so no sync will change it."},{"Field":"source","Type":"object","What it is":"Where the record came from: typed in, imported, or brought in by a connection."},{"Field":"source.type","Type":"string\nmay be null","What it is":null},{"Field":"source.ref","Type":"string\nmay be null","What it is":"The id the originating system knows it by."},{"Field":"source.connection_id","Type":"integer\nmay be null","What it is":null},{"Field":"created_at","Type":"string\nalways present","What it is":"When the row was first written."},{"Field":"updated_at","Type":"string\nalways present","What it is":"When it last changed. This is what the list is ordered by, what a cursor points into, and what updated_since compares against."}]},{"title":"GET /api/v1/value_entries","intro":"What the account's initiatives have returned. Only entries whose status is \"approved\" count toward reported ROI — see counts_toward_roi on each row.","columns":["Parameter","Type","What it means"],"rows":[{"Parameter":"limit","Type":"integer\noptional · default 100","What it means":"Rows per page, up to 500."},{"Parameter":"cursor","Type":"string\noptional","What it means":"The next_cursor from the previous page. Opaque: its shape is not part of the contract."},{"Parameter":"updated_since","Type":"string\noptional","What it means":"Only rows changed at or after this moment, which is what makes a repeat pull cheap. At or after, not after, so a caller passing back the last updated_at they saw cannot miss a row saved in the same millisecond."},{"Parameter":"initiative_id","Type":"integer\noptional","What it means":"Only rows belonging to one initiative in this account."},{"Parameter":"status","Type":"string\noptional","What it means":"Only entries with this status. Only \"approved\" counts toward reported ROI. One of: draft, calculated, reviewed, approved, disputed, archived."},{"Parameter":"period_from","Type":"string\noptional","What it means":"The start of the window. Entries are matched on where their period begins, which is how Roiva's own reports slice a period: an entry belongs to the period it starts in, so a twelve-month entry beginning in January is in Q1 and in no other quarter. Asking for a quarter therefore returns the rows the dashboard counted for it. Either bound may be given on its own."},{"Parameter":"period_to","Type":"string\noptional","What it means":"The end of the window, matched the same way — see period_from."}]},{"intro":"What a row carries.","columns":["Field","Type","What it is"],"rows":[{"Field":"id","Type":"integer\nalways present","What it is":null},{"Field":"initiative_id","Type":"integer\nalways present","What it is":null},{"Field":"amount_cents","Type":"integer\nmay be null","What it is":"Amount in cents, in the currency beside it."},{"Field":"currency","Type":"string\nmay be null","What it is":null},{"Field":"status","Type":"string\nalways present","What it is":"Only \"approved\" counts toward reported ROI. The others are on their way there or were sent back, and summing every row gives a figure that disagrees with /roi. One of: draft, calculated, reviewed, approved, disputed, archived."},{"Field":"counts_toward_roi","Type":"boolean\nalways present","What it is":"Whether this entry is in the reported figure. True exactly when status is \"approved\"."},{"Field":"entry_type","Type":"string\nmay be null","What it is":null},{"Field":"period_start","Type":"string\nmay be null","What it is":null},{"Field":"period_end","Type":"string\nmay be null","What it is":null},{"Field":"is_estimated","Type":"boolean","What it is":null},{"Field":"confidence_score","Type":"number\nmay be null","What it is":null},{"Field":"quality_score","Type":"number\nmay be null","What it is":null},{"Field":"notes","Type":"string\nmay be null","What it is":"What a person wrote about this figure in their own words — for a saving, typically what changed: their team's doing, or a vendor's pricing."},{"Field":"provenance","Type":"string\nmay be null","What it is":"Where the number came from, in one phrase: synced from a connection, calculated from a formula, or entered by hand."},{"Field":"calculation_version","Type":"integer\nmay be null","What it is":"Which version of the formula produced it."},{"Field":"formula_id","Type":"integer\nmay be null","What it is":null},{"Field":"source","Type":"object","What it is":"Where the record came from: typed in, imported, or brought in by a connection."},{"Field":"source.type","Type":"string\nmay be null","What it is":null},{"Field":"source.ref","Type":"string\nmay be null","What it is":"The id the originating system knows it by."},{"Field":"source.connection_id","Type":"integer\nmay be null","What it is":null},{"Field":"approved_at","Type":"string\nmay be null","What it is":null},{"Field":"created_at","Type":"string\nalways present","What it is":"When the row was first written."},{"Field":"updated_at","Type":"string\nalways present","What it is":"When it last changed. This is what the list is ordered by, what a cursor points into, and what updated_since compares against."}]},{"title":"GET /api/v1/metrics","intro":"The metric definitions behind the figures: what each one measures, its type and its unit.","columns":["Parameter","Type","What it means"],"rows":[{"Parameter":"limit","Type":"integer\noptional · default 100","What it means":"Rows per page, up to 500."},{"Parameter":"cursor","Type":"string\noptional","What it means":"The next_cursor from the previous page. Opaque: its shape is not part of the contract."},{"Parameter":"updated_since","Type":"string\noptional","What it means":"Only rows changed at or after this moment, which is what makes a repeat pull cheap. At or after, not after, so a caller passing back the last updated_at they saw cannot miss a row saved in the same millisecond."}]},{"intro":"What a row carries.","columns":["Field","Type","What it is"],"rows":[{"Field":"id","Type":"integer\nalways present","What it is":null},{"Field":"metric_key","Type":"string\nalways present","What it is":"The canonical key, as the metric registry spells it."},{"Field":"name","Type":"string\nalways present","What it is":null},{"Field":"description","Type":"string\nmay be null","What it is":null},{"Field":"metric_type","Type":"string\nmay be null","What it is":"count, duration, percentage, currency and so on."},{"Field":"unit","Type":"string\nmay be null","What it is":null},{"Field":"currency_metric","Type":"boolean","What it is":"Whether its readings are money."},{"Field":"active","Type":"boolean","What it is":null},{"Field":"created_at","Type":"string\nalways present","What it is":"When the row was first written."},{"Field":"updated_at","Type":"string\nalways present","What it is":"When it last changed. This is what the list is ordered by, what a cursor points into, and what updated_since compares against."}]},{"title":"GET /api/v1/observations","intro":"The readings and baselines the value formulas run on. Ordered oldest change first.","columns":["Parameter","Type","What it means"],"rows":[{"Parameter":"limit","Type":"integer\noptional · default 100","What it means":"Rows per page, up to 500."},{"Parameter":"cursor","Type":"string\noptional","What it means":"The next_cursor from the previous page. Opaque: its shape is not part of the contract."},{"Parameter":"updated_since","Type":"string\noptional","What it means":"Only rows changed at or after this moment, which is what makes a repeat pull cheap. At or after, not after, so a caller passing back the last updated_at they saw cannot miss a row saved in the same millisecond."},{"Parameter":"initiative_id","Type":"integer\noptional","What it means":"Only rows belonging to one initiative in this account."},{"Parameter":"metric_key","Type":"string\noptional","What it means":"Only readings of one metric, by its canonical key."}]},{"intro":"What a row carries.","columns":["Field","Type","What it is"],"rows":[{"Field":"id","Type":"integer\nalways present","What it is":null},{"Field":"metric_id","Type":"integer\nmay be null","What it is":null},{"Field":"metric_key","Type":"string\nmay be null","What it is":null},{"Field":"initiative_id","Type":"integer\nmay be null","What it is":null},{"Field":"value","Type":"number\nmay be null","What it is":"The reading itself, in the metric's unit."},{"Field":"role","Type":"string\nmay be null","What it is":"Whether it is a baseline or a reading."},{"Field":"baseline_method","Type":"string\nmay be null","What it is":"How a baseline was arrived at, when it is one."},{"Field":"observed_at","Type":"string\nmay be null","What it is":null},{"Field":"period_start","Type":"string\nmay be null","What it is":null},{"Field":"period_end","Type":"string\nmay be null","What it is":null},{"Field":"is_estimated","Type":"boolean","What it is":null},{"Field":"sample_size","Type":"integer\nmay be null","What it is":null},{"Field":"quality_score","Type":"number\nmay be null","What it is":null},{"Field":"source","Type":"object","What it is":"Where the record came from: typed in, imported, or brought in by a connection."},{"Field":"source.type","Type":"string\nmay be null","What it is":null},{"Field":"source.ref","Type":"string\nmay be null","What it is":"The id the originating system knows it by."},{"Field":"source.connection_id","Type":"integer\nmay be null","What it is":null},{"Field":"created_at","Type":"string\nalways present","What it is":"When the row was first written."},{"Field":"updated_at","Type":"string\nalways present","What it is":"When it last changed. This is what the list is ordered by, what a cursor points into, and what updated_since compares against."}]},{"title":"GET /api/v1/budgets","intro":"The signed-off budget, not the business case the initiatives list carries. One row per initiative, including initiatives with no budget — see `budgeted`, which says which rows belong in a variance total. Ordered oldest change first, by the initiative.","columns":["Parameter","Type","What it means"],"rows":[{"Parameter":"limit","Type":"integer\noptional · default 100","What it means":"Rows per page, up to 500."},{"Parameter":"cursor","Type":"string\noptional","What it means":"The next_cursor from the previous page. Opaque: its shape is not part of the contract."},{"Parameter":"include_sample","Type":"boolean\noptional · default false","What it means":"Include provisioned demo initiatives, which are left out by default. A warehouse that ingests them reports figures nobody spent."},{"Parameter":"initiative_id","Type":"integer\noptional","What it means":"Only rows belonging to one initiative in this account."},{"Parameter":"budgeted","Type":"boolean\noptional · default false","What it means":"Only initiatives that have an approved budget. Applied after the comparison runs, since it is not a column, so a page can come back shorter than limit while there are still more pages."}]},{"intro":"What a row carries.","columns":["Field","Type","What it is"],"rows":[{"Field":"initiative_id","Type":"integer\nalways present","What it is":null},{"Field":"budgeted","Type":"boolean\nalways present","What it is":"Whether an approved budget exists at all. False means the figures below compare spend against nothing, so these rows belong out of any variance total — which is what Roiva's own totals do."},{"Field":"status","Type":"string\nalways present","What it is":"\"over\" when either half is over, because an unspent CapEx envelope early in a build must not hide an OpEx run rate that is already over. \"scheduled\" means a budget exists but has not started. One of: no_budget, scheduled, within, over."},{"Field":"over_parts","Type":"array of string\nalways present","What it is":"Which half is over, when status is \"over\". One of: capex, opex."},{"Field":"currency","Type":"string\nmay be null","What it is":null},{"Field":"as_of","Type":"string\nalways present","What it is":"The day the comparison was made — today."},{"Field":"capex_budget_cents","Type":"integer","What it is":"The current version's envelope."},{"Field":"capex_actual_cents","Type":"integer","What it is":"CapEx spent since the budget began. Zero when budgeted is false: there is no budget window to measure over, so this is not the initiative's total spend. Read /api/v1/cost_entries for that."},{"Field":"capex_remaining_cents","Type":"integer","What it is":"Negative when the envelope is exceeded."},{"Field":"opex_budget_to_date_cents","Type":"integer","What it is":"Each month's rate summed from the month the budget began through this one, at whichever version covered each month. A revision changes the months after it and never restates the ones before."},{"Field":"opex_actual_cents","Type":"integer","What it is":"OpEx spent since the budget began. Zero when budgeted is false: there is no budget window to measure over, so this is not the initiative's total spend. Read /api/v1/cost_entries for that."},{"Field":"budget_monthly_run_rate_cents","Type":"integer","What it is":"The current version's rate, as a monthly figure."},{"Field":"actual_monthly_run_rate_cents","Type":"integer\nmay be null","What it is":"The average over the last 3 complete months the budget covered. Null until one complete month has passed."},{"Field":"budget_to_date_cents","Type":"integer\nalways present","What it is":"CapEx envelope plus OpEx to date."},{"Field":"actual_to_date_cents","Type":"integer\nalways present","What it is":"Zero when budgeted is false: there is no budget window to measure over, so this is not the initiative's total spend. Read /api/v1/cost_entries for that."},{"Field":"variance_cents","Type":"integer\nalways present","What it is":"budget_to_date_cents minus actual_to_date_cents. Positive is under budget."},{"Field":"used_ratio","Type":"number\nmay be null","What it is":"Actual over budget to date. Null when there is no budget to date to divide by."},{"Field":"spent_before_budget_cents","Type":"integer","What it is":"Spend dated before the month the budget began. Reported apart rather than charged against an envelope that did not exist yet, so it is in neither figure above."},{"Field":"opex_budget_fiscal_year_cents","Type":"integer","What it is":"The whole fiscal year's OpEx budget."},{"Field":"opex_budget_fiscal_ytd_cents","Type":"integer","What it is":"The part of it through as_of."},{"Field":"opex_actual_fiscal_ytd_cents","Type":"integer","What it is":null},{"Field":"budget_started_on","Type":"string\nmay be null","What it is":"The month the first approved version took effect."},{"Field":"revised","Type":"boolean","What it is":"Whether the budget has been changed since it was first approved."},{"Field":"version_count","Type":"integer","What it is":null},{"Field":"revision_pending","Type":"boolean","What it is":"A revision is waiting for the account Owner, because it would put the budget above the account's approval threshold. The figures here are still the approved ones."},{"Field":"current_version","Type":"object\nmay be null","What it is":"The approved version in effect, or null when there is no budget yet or every version starts in a later month."},{"Field":"current_version.id","Type":"integer","What it is":null},{"Field":"current_version.effective_from","Type":"string","What it is":"The figures apply from the whole month containing this date, not from the day — so a version effective on the 28th covers that month in full, and budget_started_on is the first of it. There is no day proration."},{"Field":"current_version.ends_on","Type":"string\nmay be null","What it is":"The last month covered, again whole-month."},{"Field":"current_version.capex_cents","Type":"integer","What it is":"A one-off total, not accrued."},{"Field":"current_version.opex_cents","Type":"integer","What it is":"A rate, per opex_cadence."},{"Field":"current_version.opex_cadence","Type":"string","What it is":"One of: monthly, quarterly, annually."},{"Field":"current_version.source","Type":"string","What it is":"Whether it came from the initiative's approval, a later revision, or was set by hand. One of: approval, revision, manual."},{"Field":"current_version.reason","Type":"string\nmay be null","What it is":"Why it was set, in the words of whoever set it."},{"Field":"current_version.set_by","Type":"object\nmay be null","What it is":"Who, inside this account. Names, never email addresses."}]},{"title":"GET /api/v1/decisions","intro":"Continue, scale, fix, pause or retire, with the rationale and the figures as they stood when it was decided. Immutable once written, so a row read today says what was known then. Ordered oldest change first.","columns":["Parameter","Type","What it means"],"rows":[{"Parameter":"limit","Type":"integer\noptional · default 100","What it means":"Rows per page, up to 500."},{"Parameter":"cursor","Type":"string\noptional","What it means":"The next_cursor from the previous page. Opaque: its shape is not part of the contract."},{"Parameter":"updated_since","Type":"string\noptional","What it means":"Only rows changed at or after this moment, which is what makes a repeat pull cheap. At or after, not after, so a caller passing back the last updated_at they saw cannot miss a row saved in the same millisecond."},{"Parameter":"initiative_id","Type":"integer\noptional","What it means":"Only rows belonging to one initiative in this account."},{"Parameter":"outcome","Type":"string\noptional","What it means":"Only decisions with this outcome. One of: continue, scale, fix, pause, retire."}]},{"intro":"What a row carries.","columns":["Field","Type","What it is"],"rows":[{"Field":"id","Type":"integer\nalways present","What it is":null},{"Field":"initiative_id","Type":"integer\nmay be null","What it is":"Null when the initiative it was about no longer exists. subject_title still says what it was."},{"Field":"subject_title","Type":"string\nalways present","What it is":"The initiative's title as it stood when the decision was made, so the row still reads after the initiative is renamed or gone."},{"Field":"outcome","Type":"string\nalways present","What it is":"What was decided. One of: continue, scale, fix, pause, retire."},{"Field":"outcome_label","Type":"string\nalways present","What it is":"How Roiva words the outcome on a page."},{"Field":"rationale","Type":"string\nalways present","What it is":"Why, in the words of whoever decided. Always present."},{"Field":"stage_before","Type":"string\nalways present","What it is":"One of: identified, reviewing, implementing, live, paused, completed, rejected, dismissed."},{"Field":"stage_after","Type":"string\nalways present","What it is":"One of: identified, reviewing, implementing, live, paused, completed, rejected, dismissed."},{"Field":"stage_changed","Type":"boolean\nalways present","What it is":"Some outcomes leave the initiative where it was."},{"Field":"decided_at","Type":"string\nmay be null","What it is":"When it was decided, which is the date to report it under."},{"Field":"decided_by","Type":"object\nmay be null","What it is":"Who, inside this account. Names, never email addresses."},{"Field":"decided_by.id","Type":"integer","What it is":null},{"Field":"decided_by.name","Type":"string","What it is":null},{"Field":"next_review_on","Type":"string\nmay be null","What it is":"When this is meant to be looked at again. Roiva suggests a date from the outcome; whoever decided can change it."},{"Field":"currency","Type":"string\nmay be null","What it is":null},{"Field":"approved_value_cents","Type":"integer\nmay be null","What it is":"Approved value at the moment of the decision. Approved only, as everywhere: this is the figure that was on the screen, not a recomputation."},{"Field":"cost_to_date_cents","Type":"integer\nmay be null","What it is":"Amount in cents, in the currency beside it."},{"Field":"net_cents","Type":"integer\nmay be null","What it is":"approved_value_cents minus cost_to_date_cents, as of the decision."},{"Field":"planned_value_cents","Type":"integer\nmay be null","What it is":"What the business case had promised in total."},{"Field":"planned_value_to_date_cents","Type":"integer\nmay be null","What it is":"The part of that plan due by the decision date."},{"Field":"roi","Type":"number\nmay be null","What it is":"The ratio as of the decision. Null where there was no cost to divide by."},{"Field":"created_at","Type":"string\nalways present","What it is":"When the row was first written."},{"Field":"updated_at","Type":"string\nalways present","What it is":"When it last changed. This is what the list is ordered by, what a cursor points into, and what updated_since compares against."}]},{"title":"GET /api/v1/integrations","intro":"What each connection is, whether it is working, and when data last arrived. Credentials, stored settings and error prose are never served — see the field descriptions for what stands in for them. Ordered oldest change first.","columns":["Parameter","Type","What it means"],"rows":[{"Parameter":"limit","Type":"integer\noptional · default 100","What it means":"Rows per page, up to 500."},{"Parameter":"cursor","Type":"string\noptional","What it means":"The next_cursor from the previous page. Opaque: its shape is not part of the contract."},{"Parameter":"updated_since","Type":"string\noptional","What it means":"Only rows changed at or after this moment, which is what makes a repeat pull cheap. At or after, not after, so a caller passing back the last updated_at they saw cannot miss a row saved in the same millisecond."},{"Parameter":"platform","Type":"string\noptional","What it means":"Only connections to one platform."},{"Parameter":"status","Type":"string\noptional","What it means":"Only connections in this state. One of: active, paused, error, disconnected."}]},{"intro":"What a row carries.","columns":["Field","Type","What it is"],"rows":[{"Field":"id","Type":"integer\nalways present","What it is":null},{"Field":"platform","Type":"string\nalways present","What it is":"Which system this connects to."},{"Field":"name","Type":"string\nmay be null","What it is":null},{"Field":"description","Type":"string\nmay be null","What it is":null},{"Field":"status","Type":"string\nalways present","What it is":"Whether it is working. \"error\" means syncs are failing; \"paused\" and \"disconnected\" mean somebody stopped it. One of: active, paused, error, disconnected."},{"Field":"auth_type","Type":"string\nmay be null","What it is":"How it authenticates. The credentials themselves are never served. One of: oauth, api_key, basic, webhook, github_app, service_account."},{"Field":"last_sync_status","Type":"string\nmay be null","What it is":"How the most recent sync ended."},{"Field":"last_synced_at","Type":"string\nmay be null","What it is":"When data last arrived. The field to watch: a connection can read \"active\" and still not have synced for a week."},{"Field":"reauth_required_at","Type":"string\nmay be null","What it is":"Set when the platform refused the grant Roiva holds. Non-null means no amount of retrying will fix it and a person has to reconnect."},{"Field":"external_account_id","Type":"string\nmay be null","What it is":"What the platform calls the account on its side, for joining to its own data."},{"Field":"external_account_name","Type":"string\nmay be null","What it is":null},{"Field":"primary_source_categories","Type":"array of string\nalways present","What it is":"The categories this connection is the canonical source for. Where two connections could serve the same category, only the primary one's readings are used."},{"Field":"metric_categories","Type":"array of string\nalways present","What it is":"What this platform's connections can serve at all, whether or not this one is primary."},{"Field":"simulated","Type":"boolean\nalways present","What it is":"A connection whose syncs are answered by Roiva's simulator rather than by the platform. Only an internal Roiva account can hold one."},{"Field":"connected_by","Type":"object\nmay be null","What it is":"Who, inside this account. Names, never email addresses."},{"Field":"connected_by.id","Type":"integer","What it is":null},{"Field":"connected_by.name","Type":"string","What it is":null},{"Field":"created_at","Type":"string\nalways present","What it is":"When the row was first written."},{"Field":"updated_at","Type":"string\nalways present","What it is":"When it last changed. This is what the list is ordered by, what a cursor points into, and what updated_since compares against."}]},{"title":"GET /api/v1/initiatives/{id}","intro":"The same fields the list serves, for an initiative a caller already has the id of. An id belonging to another account answers 404 rather than 403, because a 403 would confirm it exists.","columns":["Parameter","Type","What it means"],"rows":[{"Parameter":"id","Type":"integer\nrequired","What it means":"The initiative's Roiva id."}]},{"intro":"What it answers with.","columns":["Field","Type","What it is"],"rows":[{"Field":"id","Type":"integer\nalways present","What it is":null},{"Field":"title","Type":"string\nalways present","What it is":null},{"Field":"description","Type":"string\nmay be null","What it is":null},{"Field":"hypothesis","Type":"string\nmay be null","What it is":null},{"Field":"stage","Type":"string\nalways present","What it is":"Where it is in its lifecycle. One of: identified, reviewing, implementing, live, paused, completed, rejected, dismissed."},{"Field":"is_sample","Type":"boolean\nalways present","What it is":"Provisioned demo data. Left out of lists unless include_sample=true, because a warehouse that ingests it reports figures nobody spent."},{"Field":"category","Type":"string\nmay be null","What it is":null},{"Field":"priority","Type":"integer\nmay be null","What it is":"Lower is higher priority."},{"Field":"source","Type":"string\nmay be null","What it is":"How the initiative came to exist."},{"Field":"business_unit","Type":"string\nmay be null","What it is":null},{"Field":"department","Type":"string\nmay be null","What it is":null},{"Field":"gl_dimension_value","Type":"string\nmay be null","What it is":null},{"Field":"owner","Type":"object\nmay be null","What it is":"Who, inside this account. Names, never email addresses."},{"Field":"owner.id","Type":"integer","What it is":null},{"Field":"owner.name","Type":"string","What it is":null},{"Field":"confidence_score","Type":"number\nmay be null","What it is":null},{"Field":"roi_time_horizon_years","Type":"integer\nmay be null","What it is":null},{"Field":"currency","Type":"string\nmay be null","What it is":null},{"Field":"expected_capex_cents","Type":"integer\nmay be null","What it is":"Amount in cents, in the currency beside it."},{"Field":"expected_opex_cents","Type":"integer\nmay be null","What it is":"Amount in cents, in the currency beside it."},{"Field":"expected_cost_savings_cents","Type":"integer\nmay be null","What it is":"Amount in cents, in the currency beside it."},{"Field":"expected_revenue_uplift_cents","Type":"integer\nmay be null","What it is":"Amount in cents, in the currency beside it."},{"Field":"started_at","Type":"string\nmay be null","What it is":null},{"Field":"went_live_at","Type":"string\nmay be null","What it is":null},{"Field":"approved_at","Type":"string\nmay be null","What it is":null},{"Field":"closed_at","Type":"string\nmay be null","What it is":null},{"Field":"submitted_for_review_at","Type":"string\nmay be null","What it is":null},{"Field":"created_at","Type":"string\nalways present","What it is":"When the row was first written."},{"Field":"updated_at","Type":"string\nalways present","What it is":"When it last changed. This is what the list is ordered by, what a cursor points into, and what updated_since compares against."}]}]}