Table of Contents
Top
upsquad/bulkimport/v1/bulkimport.proto
ApplyCsvRequest
ApplyCsvRequest commits a previously-previewed CSV in 50-row chunks.
| Field | Type | Label | Description |
|---|
| org_id | string | | org_id is the tenant the CSV is applied to. |
| kind | ImportKind | | kind selects the row shape (users vs groups). |
| csv_payload | bytes | | csv_payload is the raw CSV bytes. Max 10 MiB. |
| request_id | string | | request_id is the client-generated idempotency key. ≤128 chars. Same (org_id, request_id) MUST short-circuit on retry. |
ApplyCsvResponse
ApplyCsvResponse is one frame of the server-streaming apply response.
| Field | Type | Label | Description |
|---|
| kind | ApplyCsvResponse.Kind | | kind discriminates the frame type. |
| job_id | string | | job_id is the import_jobs.id value. |
| status | JobStatus | | status is the current status of the job. |
| total_rows | int32 | | total_rows is the total number of parsed rows. |
| processed_rows | int32 | | processed_rows is the number of rows processed so far (running total). |
| error_rows | int32 | | error_rows is the number of rows that failed validation / write. |
| row_errors | RowError | repeated | row_errors is only populated on the terminal frame; truncated at 1000. |
GetImportJobRequest
GetImportJobRequest fetches a single import_jobs row by id.
| Field | Type | Label | Description |
|---|
| org_id | string | | org_id is the tenant (must match job.org_id). |
| job_id | string | | job_id is the import_jobs.id value. |
GetImportJobResponse
GetImportJobResponse returns the requested import job.
| Field | Type | Label | Description |
|---|
| job | ImportJob | | job is the persisted import_jobs row. |
ImportJob
ImportJob is the domain model for a row in import_jobs.
| Field | Type | Label | Description |
|---|
| id | string | | id is the row primary key (uuid). |
| org_id | string | | org_id is the tenant. |
| kind | ImportKind | | kind is the row shape. |
| status | JobStatus | | status is the lifecycle state. |
| total_rows | int32 | | total_rows is the number of data rows in the CSV. |
| processed_rows | int32 | | processed_rows is the number of rows processed. |
| error_rows | int32 | | error_rows is the number of rows that errored. |
| errors | RowError | repeated | errors is the capped per-row error list (≤1000). |
| started_at | google.protobuf.Timestamp | | started_at is when the job transitioned to running. |
| completed_at | google.protobuf.Timestamp | | completed_at is when the job reached a terminal status. |
| created_at | google.protobuf.Timestamp | | created_at is when the job row was inserted. |
| updated_at | google.protobuf.Timestamp | | updated_at is the latest write timestamp. |
| submitted_by_member_id | string | | submitted_by_member_id is the uploader's member id; empty for SCIM. |
| source_ref | string | | source_ref is the opaque source pointer (vault:// or scim_sync_runs.id). |
PreviewCsvRequest
PreviewCsvRequest parses a CSV in-memory and diffs against current state.
| Field | Type | Label | Description |
|---|
| org_id | string | | org_id is the tenant under which the CSV is interpreted. Must match the caller's RLS scope. |
| kind | ImportKind | | kind selects the row shape (users vs groups). |
| csv_payload | bytes | | csv_payload is the raw CSV bytes. Max 10 MiB (≈10k rows). |
PreviewCsvResponse
PreviewCsvResponse is one frame of the server-streaming preview
response. Exactly one of row or summary is set per frame.
| Field | Type | Label | Description |
|---|
| row | PreviewRow | | row is emitted for every parsed CSV row in order. |
| summary | PreviewSummary | | summary is the terminal frame with aggregate counters. |
PreviewRow
PreviewRow is the diff classification for a single CSV row.
| Field | Type | Label | Description |
|---|
| row_index | int32 | | row_index is 1-based and excludes the header row. |
| outcome | RowOutcome | | outcome is the diff classification. |
| key | string | | key is the lookup value (email for users, path for groups) the server used to resolve the row against current state. |
| error_message | string | | error_message is populated when outcome=ERROR. |
| changed_fields | string | repeated | changed_fields lists the field names that differ from current state when outcome=UPDATE. Empty otherwise. |
PreviewSummary
PreviewSummary is the terminal aggregate of a PreviewCsv stream.
| Field | Type | Label | Description |
|---|
| total_rows | int32 | | total_rows is the number of data rows parsed (excluding header). |
| create_count | int32 | | create_count is the number of rows with outcome=CREATE. |
| update_count | int32 | | update_count is the number of rows with outcome=UPDATE. |
| noop_count | int32 | | noop_count is the number of rows with outcome=NOOP. |
| error_count | int32 | | error_count is the number of rows with outcome=ERROR. |
RowError
RowError is a structured per-row error entry.
| Field | Type | Label | Description |
|---|
| row_index | int32 | | row_index is 1-based (data-row index, header excluded). |
| code | string | | code is a stable machine-readable error code. |
| message | string | | message is the human-readable error detail. |
ApplyCsvResponse.Kind
Kind names the event shape carried by this frame.
| Name | Number | Description |
|---|
| KIND_UNSPECIFIED | 0 | Default zero value — never valid on the wire. |
| KIND_JOB_ACCEPTED | 1 | JOB_ACCEPTED fires once when the import_jobs row is inserted (or resolved from idempotency cache). Contains the job id. |
| KIND_CHUNK_PROCESSED | 2 | CHUNK_PROCESSED fires after each 50-row chunk commits. |
| KIND_JOB_COMPLETED | 3 | JOB_COMPLETED is the terminal event. Contains the final status and counters. |
ImportKind
ImportKind names the shape the CSV payload targets. These match the
CHECK enum on import_jobs.kind (migration 068) exactly.
| Name | Number | Description |
|---|
| IMPORT_KIND_UNSPECIFIED | 0 | Default zero value — never valid on the wire. |
| IMPORT_KIND_CSV_USERS | 1 | CSV payload targets members (users). |
| IMPORT_KIND_CSV_GROUPS | 2 | CSV payload targets org_units (groups). |
JobStatus
JobStatus mirrors the CHECK enum on import_jobs.status.
| Name | Number | Description |
|---|
| JOB_STATUS_UNSPECIFIED | 0 | Default zero value — never valid on the wire. |
| JOB_STATUS_QUEUED | 1 | Inserted, awaiting work. |
| JOB_STATUS_RUNNING | 2 | Actively being processed. |
| JOB_STATUS_SUCCEEDED | 3 | Completed with zero row errors. |
| JOB_STATUS_PARTIAL | 4 | Completed but one or more rows errored. |
| JOB_STATUS_FAILED | 5 | Terminal failure before any row was committed. |
RowOutcome
RowOutcome classifies the diff/apply outcome for a single CSV row.
| Name | Number | Description |
|---|
| ROW_OUTCOME_UNSPECIFIED | 0 | Default zero value — never valid on the wire. |
| ROW_OUTCOME_CREATE | 1 | Row represents a new entity to be created. |
| ROW_OUTCOME_UPDATE | 2 | Row represents an update to an existing entity. |
| ROW_OUTCOME_NOOP | 3 | Row matches current state exactly; no write required. |
| ROW_OUTCOME_ERROR | 4 | Row failed validation and will not be applied. |
| ROW_OUTCOME_SKIPPED | 5 | Apply-only: row was skipped because idempotency kicked in. |
BulkImportService
BulkImportService is the Connect-RPC surface for CSV preview + apply.
| Method Name | Request Type | Response Type | Description |
|---|
| PreviewCsv | PreviewCsvRequest | PreviewCsvResponse stream | PreviewCsv parses and validates a CSV payload without touching tenant state. The server streams one PreviewCsvResponse per parsed row followed by a terminal summary response. |
| ApplyCsv | ApplyCsvRequest | ApplyCsvResponse stream | ApplyCsv commits the parsed rows in 50-row chunks. Idempotent on (org_id, request_id): a retry returns the original job's progress without re-executing side effects, but ONLY when the prior job is in a terminal state (succeeded / partial / failed). A retry that hits a non-terminal row (queued / running) is rejected with FailedPrecondition so partial work is never misreported as complete (#619). The server streams one ApplyCsvResponse per chunk plus a terminal response with kind=JOB_COMPLETED. |
| GetImportJob | GetImportJobRequest | GetImportJobResponse | GetImportJob returns the current state of a previously-submitted import job. Primarily used by the console to resume progress tracking after a transient network drop. |
Scalar Value Types
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
|---|
| double | | double | double | float | float64 | double | float | Float |
| float | | float | float | float | float32 | float | float | Float |
| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass |
| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |