
Viventium API Architecture, Authentication, and Data Access
Summarise the blog with AI
.jpg)
Key takeaways
- Viventium's Integration API authenticates with a cookie returned from a login call, not an OAuth or bearer token, so your HTTP client needs a cookie jar rather than an
Authorizationheader. - Every request addresses data through a Client, Company, Division, Employee hierarchy, and the scope appears as path segments rather than query parameters.
- The export and import surface covers roughly 50 endpoint families, from employee records and benefit enrollments to licences, dependents, and direct deposits.
- Three details cause most first-build failures:
v1/importsplural versusv1/importsingular, theactionversusimportActionparameter split, and endpoints that accept no query parameters at all. - Session lifetime, rate limits, MFA, IP allowlisting, the permission model, and credential provisioning are not stated in the public reference. Confirm each with Viventium before you build around an assumption.
Viventium API architecture, authentication, and data access
Ask Viventium's Integration API for an employee record and it wants four pieces of context first: client, company, division, and the record's own identifier. That is the shape of the whole API, a hierarchy rather than a flat list of endpoints.
Getting in is the part that catches people. POST v1/auth/login does not return a bearer token or start an OAuth exchange. It returns a cookie, and your integration has to hold onto it the way a browser session would.
That distinction is easy to miss, because Viventium's public reference is organised alphabetically by endpoint rather than by what a reader needs first. This page covers the architecture, the auth flow, the real shape of the export and import surface, the path conventions that break a first build, and what to confirm with Viventium before production.
What the Viventium Integration API is
Viventium's own documentation describes it as a RESTful Integration API for the Paystream system, grouped by function rather than by object.
The structure underneath is a hierarchy. Client sits above Company, Company above Division, and Division above the records you want. Every request walks down that tree. You do not ask for "an employee," you ask for an employee inside a division, inside a company, inside a client.
The identifiers name the rungs:
clientCodeidentifies the client account at the top of the tree.companyCodeidentifies a company under that client.divisionCodeanddivisionIdidentify a division, referenced by code or by internal ID depending on the endpoint.employeeNumberidentifies an individual employee within a division.payrollIdandserviceCodeidentify a specific payroll run or import service.
Address a division that belongs to a different company and you will not reach the record you meant. The public documentation does not say how the API signals that mismatch, so treat an unexpected empty response as a hierarchy problem to check first.
How authentication works
Most REST APIs built in the last decade hand you a bearer token. Viventium's public documentation shows a cookie instead.
The flow is short:
- Log in. Send
POST v1/auth/loginwithUsernameandPasswordin the body. JSON, XML, and form-urlencoded are all accepted. - Receive the cookie. The response returns what Viventium's documentation calls an Authentication Cookie.
- Reuse it. Attach that cookie to every later request instead of an
Authorizationheader. - Log out.
POST v1/auth/logoutends the session explicitly.
This is the mechanism RFC 6265 defines. The server sets state on the client, and the client returns that state on every later request. It is a session, not a credential you can decode or hand to a background worker the way you would a JWT.
The practical consequence shows up in your HTTP client. A library configured to attach a bearer token will do nothing useful here. You need a client that holds a cookie jar, sends it automatically to the same host, and re-authenticates when the server stops accepting it.
One caveat on the OAuth question
Nothing in the public reference documents an OAuth flow. Two endpoints do hint at something adjacent: POST v1/resource/register takes code, callbackUrl, and state, and POST v1/user-info/token issues a token for an external partner. Those are authorization-code parameter names. Neither endpoint carries public documentation.
The reasonable read is that a partner registration path exists that the public reference does not describe. Ask Viventium about it before you assume username and password is the only way in.
Reading data: the export endpoints
The export surface is wider than most summaries suggest. Alongside employees, payroll, benefits, time, deductions, and PTO, it covers licences and certifications, dependents, emergency contacts, direct deposits, employee allocations, cost centres, jobs, locations, rates, earnings, taxes, employee assets, onboarding plans, billing items, and an events log. Separate prefixes exist for LMS, supplemental benefits, on-demand pay, time and attendance, scheduling, and AMS partners.
The path convention matters more than the object list. Scope is a path prefix, not a query parameter, and the same object is usually addressable at four levels:
Not every object is exposed at every level. Benefit enrollments, for example, are addressable at division and employee level only:
GET v1/export/companies/{companyCode}/divisions/{divisionCode}/employee-benefit-enrollments
Every one of these returns Viventium's own shape: its own field names, its own enumerations for pay types and coverage levels, its own way of expressing a deduction. That is fine when Viventium is the only payroll system you read from. It becomes a bigger problem when it is the third.
Writing data: imports and copy
The write surface uses POST for imports and copy actions and DELETE for removals. Three conventions here cause most first-build failures, and none of them is obvious from the index.
1. Plural imports, singular import
Bulk operations use v1/imports. Scoped deletes use v1/import, singular:
Getting that wrong produces a 404 that reads like a permissions problem.
2. The action parameter is not consistently named
Some import endpoints take ?action={action}. Others take ?importAction={importAction}. There is no rule you can infer from the object:
POST v1/imports/deductions?action={action}&allowSameFile={allowSameFile}POST v1/imports/employee-benefit-enrollments?importAction={importAction}&allowSameFile={allowSameFile}
3. Some endpoints take no query parameters at all
POST v1/imports/employees accepts none. The payload is a collection of employee objects, and the company and division live inside each object as companyCode and divisionCode, or as a nested divisionKey.
That employee payload is also the deepest object in the API. A single import can carry direct deposits, scheduled deductions, scheduled earnings, allocations, emergency contacts, licences, PTO accruals, dependents, benefit enrollments, education history, previous employers, reviews, trainings, skills, custom fields, notes, assets, and events, all nested in one record.
Copy actions
Copy endpoints duplicate configuration between divisions, and they are unusually granular. POST v1/copy/companies/{companyCode}/divisions/{divisionCode}/employees takes more than twenty boolean flags, one per data category, including copyBenefitEnrollments, copyScheduledDeductions, copyPTOAccruals, and copyDependents.
Read the counts, not the status code
Viventium's import and copy actions report how many records were new, updated, and errored, rather than a single success flag. Build your integration to read those counts. A 200 response with forty errors inside it is a failed import wearing a success response.
What the public documentation does not tell you
Seven things a production integration normally needs are absent from the public reference. None of this means Viventium lacks them. It means the documentation does not say, and each is worth confirming directly.
- Credential provisioning. How you obtain API access, and whether partner registration is required, is not documented. The undocumented
v1/resource/registerendpoint suggests there is a process. This is the first thing that blocks a real build. - Session lifetime. Not stated, so treat a 401 as the signal to re-authenticate rather than assume a fixed window.
- Cookie attributes. The cookie's name, and whether it is marked
HttpOnlyandSecure, are not documented. OWASP's session management guidance treats any session identifier in a cookie as sensitive material needing those protections, which is reason enough to ask. - Multi-factor authentication. Whether MFA can apply to API logins is not documented. The flow shown accepts a username and password and nothing else.
- IP allowlisting. Not documented, so do not assume you need a static egress address, or that one would be accepted.
- Rate limits. Not documented. A bulk export or import job should back off conservatively.
- The permission model. Nothing states what a given login can and cannot reach, which matters as soon as more than one team shares credentials.
Reaching Viventium through a normalised model
Everything above is enough to build a working Viventium integration. If Viventium is the only system you connect to, that is likely where this stops.
It stops being true the moment Viventium is one of several. A benefits platform reading from Viventium and a dozen other payroll and HRIS systems holds a dozen different auth models, a cookie here, OAuth there, an API key somewhere else, and a dozen different shapes for the same underlying fact.
Bindbee connects to 67+ HRIS, payroll, ATS, and benefits systems through one API, Viventium included. Each connector authenticates the way its source system requires, with no screen scraping. Connectivity is direct API or SFTP depending on the system, and Viventium is an API connector.
Bindbee normalises what comes back into 40+ unified data models across HRIS, payroll, ATS, and LMS. On the Viventium connector that covers employee, company, employments, compensation, bank info, benefits, employer benefits, dependents, dependent benefits, groups, pay groups, payroll runs, time off balance, and timesheet entries.
The mapping is concrete. Viventium's enrollment fields land on named fields in the unified benefits model:
Where a field genuinely does not fit the unified model, Custom Fields carries it through anyway, mapped by JMESPath onto the object it belongs on.
Production connectors sync every 24 hours by default, and the interval is configurable. Webhooks fire when a sync starts, finishes, or fails, and when synced records change, so you receive a push instead of polling. Bindbee is SOC 2 Type II, ISO 27001, HIPAA, and GDPR compliant, and a standard BAA template is available.
None of this is necessary for a single client, single system Viventium job. Direct integration is the right call there. It is the platform reaching Viventium alongside ten other systems that a normalised layer is built for.
Healthee replaced 15 custom integrations with Bindbee. Newfront cut client onboarding from 8 to 12 weeks down to 48 hours.
We build the integrations. You build the product.
FAQ
Does the Viventium API use OAuth?
Not according to its public documentation. POST v1/auth/login returns what the documentation calls an Authentication Cookie rather than an OAuth token, and no client-credentials or authorization-code grant is documented. Two undocumented endpoints, v1/resource/register and v1/user-info/token, use authorization-code parameter names, so ask Viventium whether a partner flow exists.
How do I get Viventium API credentials?
The public reference does not say. It documents the login call but not how access is provisioned, and an undocumented registration endpoint suggests a partner process. Contact Viventium before scoping a timeline.
What is the difference between v1/imports and v1/import?
Plural v1/imports is used for bulk operations across a division or client. Singular v1/import is used for scoped deletes that name a specific company, division, employee, and record. They are different paths, and mixing them returns a 404.
Does the Viventium API return benefit enrollments?
Yes. GET v1/export/companies/{companyCode}/divisions/{divisionCode}/employee-benefit-enrollments returns them at division level, and the same path with ?employeeNumber= narrows to one employee. A separate supplemental benefits prefix covers carrier-facing records.





