v4.0.0: Align SDK with stabilized API + usage/audit/compliance/bulk resources#1
Merged
Conversation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Remove /v1/credits/* endpoints (balance, usage, history) and replace with GET /v1/usage/current backed by the live API handler. Adds GroupUsage and UsageSnapshot Pydantic models with nullable used/limit fields matching the Rust wire format (camelCase resetSeconds). InsufficientCreditsError retained: ApiError::InsufficientCredits still maps to HTTP 402 in errors.rs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ing Task 2 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…'starter') SDK surfaces tier as a free-form string and the API already maps the legacy 'starter' alias to 'basic' server-side (models/access.rs), so no SDK-side validator is needed; only the stale test fixture referenced 'starter'. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…EAKING) The API emits X-RateLimit-Group/-Window/-Limit/-Remaining/-Reset and no X-Credits-* headers (middleware/rate_limit_headers.rs). Drop ResponseMeta credits_used/credits_remaining; add rate_limit_group and rate_limit_window to cover the complete header set. Update affected meta tests. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… dossier citations) - UboPerson.person_id: int -> str (API sends a UUID; int caused ValidationError) - UboResponse: add ultimate_parent_lei / ultimate_parent_name (were dropped) - DiffEntry.from_value: alias to wire 'from' (was 'fromValue' -> always None) - Dossier: add citations: list[Citation] + new Citation model (were dropped) - Add regression tests for all three. Verified against handler signatures in companies.rs/ownership.rs, changes.rs, dossiers.rs and kg/types.rs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…mark, persons, MigrationResponse) - Company: add status_canonical, legal_form_code, auditor_opt_out, auditor_source, data_quality_score (all nullable, per CompanyResponse). - AuditCandidate: add currency, change_count, score, risk_indicators, auditor_tenure_years (handler returns these; were dropped). - BenchmarkDimension: company_value and peers_with_data are non-optional on the wire (fix wrong nullability). - MigrationResponse: add data_coverage_note. - PersonSearchResult/PersonDetail: add nationality_iso, nationality_display. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nges/watchlists include_internal, persons.search filters) - companies.list: add 17 SearchParams filters (foundedAfter, minChanges, isFinmaRegulated, noga*, dataQuality*, statusCanonical, legalFormCode, hasAuditor/hasLei/hasWikidata, enriched, boardMemberSearch, uids). - companies.events / changes.list / changes.by_company / watchlists.events: add include_internal. - persons.search: add role_category, signing_authority, canton, nationality_iso, place_of_origin, is_active, sort_by, sort_desc. - Add wire-key serialization regression test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- teams.Team: drop phantom credit_balance/monthly_credits; add
stripe_subscription_id, current_period_end, cancellation_effective_at.
- teams.BillingSummary/MemberUsage: drop credit fields the API no longer returns.
- watchlists.WatchlistCompanyEntry.name: non-optional (API guarantees it).
- comparative.auditor_analysis: non-optional (handler always emits it).
- ai.search: typed AiSearchResult projection instead of full Company.
- screening.browse_sanctions: send snake_case entity_type (handler expects it)
and fix locals() leaking _build_params into the query string.
- pipelines: add missing update() method (PUT /v1/pipelines/{id}).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… API note Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…k, watches resources New resources (all sync+async, modeled from handler signatures): - settings: get/update preferences (free-form Preferences, extra=allow) - notifications: list, mark_read, get/update preferences, test - sync: status (pipeline freshness) - audit: playbook(uid) (full procedure/step tree) - compliance: scope(uid) (regulation→control→evidence tree) - risk: v2(uid) (Bayesian risk score) - bulk: export (CSV bytes), screening, add_to_watchlist (multipart) - watches: list, add, remove Plus ownership.analytics(uid) and analytics.prospects() on existing resources. Transport: thread optional files= through _request/_request_model for the bulk watchlist multipart upload. Gap script now reports 0 phantom endpoints. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- pyproject: register 'live' marker, default addopts '-m not live'. - tests/live/: session-scoped client fixture (skips without VYNCO_API_KEY), read-only smoke tests for health/usage/companies/changes with tier-gate (403) treated as skip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Bump version 3.2.1 -> 4.0.0 (_constants.py, pyproject.toml). - CHANGELOG: full 4.0.0 entry (breaking changes, additions, fixes). - README: rewrite resource table (remove credits, add usage/settings/ notifications/sync/audit/compliance/risk/bulk/watches/pipelines/reports/ saved_searches; update ai/changes/analytics/ownership/screening rows). - Fix stale ResponseMeta.credits_used/remaining references in README and examples (quickstart, bulk_export) -> rate_limit_* fields. - Format scripts/api_gap.py. Gate: ruff (format+lint), mypy (78 files), pytest (69 passed, 6 live deselected) all green. Gap script: 0 phantom endpoints. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…metadata intro Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hardcoded CHE-105.805.080 404s against prod; derive a real UID from a search so the live smoke test is robust to dataset contents. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…key) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add examples/_common.py with get_client() (friendly missing-key message) and a section() context manager that degrades gracefully on ForbiddenError (tier gate), RateLimitError, and transient ServerError/ServiceUnavailableError. Refactor all 8 examples to wrap each section so the same script runs end-to-end on Free, Professional, or Enterprise keys instead of crashing on the first gated call. Verified live against production with a free-tier key: all 8 run to completion (tier-gated sections print a clear skip note; free-tier sections show real data). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- pyproject: [project.optional-dependencies].notebooks = matplotlib/seaborn/ networkx/numpy/jupyter/ipykernel so the example notebooks run via 'pip install vynco[notebooks]' or 'uv run --extra notebooks ...'. - notebooks/README: document the extra + the Professional-tier requirement. - test_empty_api_key_raises_config_error: delenv VYNCO_API_KEY so it stays hermetic when the key is exported for the live suite. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Full alignment of the
vyncoSDK to the now-stabilized VynCo API, released as 4.0.0. The axum router (VynCorpApi/src/routes/) was treated as the source of truth — the OpenAPI doc is incomplete (~40 live routes undocumented), so reconciliation was driven by handler signatures and verified with a reproducible route-gap script (now 0 phantom endpoints).Breaking changes
client.credits(+ Credit* types) → addedclient.usage.current()(/v1/usage/current).ResponseMeta: droppedcredits_used/credits_remaining(API emits noX-Credits-*); now exposes the fullX-RateLimit-*set (addedrate_limit_group/rate_limit_window).starter→basic(API normalizes the legacy alias).Team/BillingSummary/MemberUsage: removed phantom credit fields;Teamgainedstripe_subscription_id/current_period_end/cancellation_effective_at.UboPerson.person_idint→str(UUID);AiSearchResponse.results→list[AiSearchResult];ComparativeResponse.auditor_analysisandWatchlistCompanyEntry.namenow non-optional.P0 correctness fixes (with regression tests)
DiffEntrynow reads wire keyfrom(was aliasedfromValue→ alwaysNone).UboPerson.person_idUUID type (wasint→ValidationError).Dossier.citations+Citationmodel (was silently dropped).screening.browse_sanctionssends snakeentity_typeand no longer leaks_build_paramsinto the query.Added
ownership.analytics,analytics.prospects,pipelines.update.companies.listfilters,include_internal(events/changes/watchlists), 8persons.searchfilters.scripts/api_gap.py(reproducible diff) + opt-in@pytest.mark.livesmoke suite.Test plan
uv run pytest— 69 passed, 6 live deselecteduv run mypy src/— clean (78 files)uv run ruff check+ruff format --check— cleanpython scripts/api_gap.py— 0 phantom (only/audit-logdeferred, out of scope)/healthVYNCO_API_KEY:VYNCO_API_KEY=... uv run pytest -m live -vFollow-up (API repo, optional)
GET /v1/sanctionsis the only query struct using snake_case (entity_type); recommend adding#[serde(rename_all = "camelCase")]so the SDK special-case can be removed. Seedocs/superpowers/plans/2026-05-20-sdk-api-alignment.md.🤖 Generated with Claude Code