xml

package
v1.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 22, 2025 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package xml provides access to legacy QuickBase XML API endpoints.

The XML API contains endpoints that have no JSON API equivalent, primarily for retrieving role and schema information. This package wraps those endpoints while reusing the main client's authentication, retry, and throttling infrastructure.

Rate Limits

The XML API has different rate limits than the JSON API:

  • XML API: 10 requests per second per table (dynamically enforced)
  • JSON API: 100 requests per 10 seconds per user token

The SDK uses retry logic with exponential backoff for 429 responses. Note that the proactive throttle (WithProactiveThrottle) is designed for the JSON API and doesn't account for the XML API's per-table limits.

Deprecation Notice

The QuickBase XML API is legacy and may be discontinued in the future. Use JSON API methods (via the main quickbase package) where possible. This package will be removed when QuickBase discontinues the XML API.

To find all XML API-related code for removal, search for: grep -r "XML-API"

Usage

Create an XML client from an existing quickbase.Client:

import (
    "github.com/DrewBradfordXYZ/quickbase-go"
    "github.com/DrewBradfordXYZ/quickbase-go/xml"
)

// Main client for JSON API
qb, _ := quickbase.New("myrealm", quickbase.WithUserToken("..."))

// XML client for legacy endpoints
xmlClient := xml.New(qb)

// Get all roles defined in an app
roles, err := xmlClient.GetRoleInfo(ctx, appId)

// Get comprehensive schema information
schema, err := xmlClient.GetSchema(ctx, tableId)

Available Endpoints

App Discovery:

Role Management:

Group Management:

User Management:

Application Variables:

Code Pages:

Field Management:

Schema Information:

  • Client.GetSchema: Get comprehensive app/table metadata including fields, reports, and variables

Record Information:

Index

Constants

View Source
const (
	// ErrCodeSuccess indicates no error
	ErrCodeSuccess = 0

	// ErrCodeUnauthorized indicates the user is not authorized for this action
	ErrCodeUnauthorized = 4

	// ErrCodeInvalidInput indicates invalid input parameters
	ErrCodeInvalidInput = 5

	// ErrCodeNoSuchDatabase indicates the database/table does not exist
	ErrCodeNoSuchDatabase = 6

	// ErrCodeAccessDenied indicates access to the resource is denied
	ErrCodeAccessDenied = 7

	// ErrCodeInvalidTicket indicates the authentication ticket is invalid or expired
	ErrCodeInvalidTicket = 8

	// ErrCodeNoSuchRecord indicates the record does not exist
	ErrCodeNoSuchRecord = 30

	// ErrCodeNoSuchField indicates the field does not exist
	ErrCodeNoSuchField = 31

	// ErrCodeNoSuchUser indicates the user does not exist
	ErrCodeNoSuchUser = 33
)

Common QuickBase XML API error codes

Variables

This section is empty.

Functions

func IsInvalidTicket

func IsInvalidTicket(err error) bool

IsInvalidTicket returns true if the error indicates an invalid or expired ticket.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound returns true if the error indicates a resource was not found.

func IsUnauthorized

func IsUnauthorized(err error) bool

IsUnauthorized returns true if the error is an authorization error.

Types

type AddReplaceDBPageResult

type AddReplaceDBPageResult struct {
	// PageID is the ID of the page that was added or replaced
	PageID int
}

AddReplaceDBPageResult contains the response from API_AddReplaceDBPage.

type BaseResponse

type BaseResponse struct {
	XMLName   xml.Name `xml:"qdbapi"`
	Action    string   `xml:"action"`
	ErrCode   int      `xml:"errcode"`
	ErrText   string   `xml:"errtext"`
	ErrDetail string   `xml:"errdetail"`
}

BaseResponse contains the common fields in all XML API responses.

type Caller

type Caller interface {
	// Realm returns the QuickBase realm name (e.g., "mycompany").
	Realm() string

	// DoXML makes an XML API request and returns the raw response body.
	// The action parameter specifies the QUICKBASE-ACTION header value.
	DoXML(ctx context.Context, dbid, action string, body []byte) ([]byte, error)
}

Caller defines the minimal interface required to make XML API calls. This is implemented by *client.Client (and transitively by *quickbase.Client).

By depending on this interface rather than concrete types, the xml package:

  • Avoids import cycles with the main package
  • Remains easily testable with mock implementations
  • Can be cleanly removed when XML API is deprecated

type ChildTable

type ChildTable struct {
	// Name is the internal name (e.g., "_dbid_my_table")
	Name string `xml:"name,attr"`

	// DBID is the table's database ID
	DBID string `xml:",chardata"`
}

ChildTable represents a child table in an application.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client provides methods for calling legacy QuickBase XML API endpoints.

Create a Client using New with an existing quickbase.Client or client.Client.

func New

func New(caller Caller, opts ...Option) *Client

New creates an XML API client from an existing QuickBase client.

The caller parameter should be a *quickbase.Client or *client.Client, both of which implement the Caller interface.

Example:

qb, _ := quickbase.New("myrealm", quickbase.WithUserToken("..."))
xmlClient := xml.New(qb)

// With schema for alias support:
xmlClient := xml.New(qb, xml.WithSchema(resolvedSchema))

func (*Client) AddGroupToRole

func (c *Client) AddGroupToRole(ctx context.Context, appId, groupId string, roleId int) error

AddGroupToRole assigns a group to a role in an application.

Example:

err := xmlClient.AddGroupToRole(ctx, appId, "1217.dgpt", 12)

See: https://help.quickbase.com/docs/api-addgrouptorole

func (*Client) AddReplaceDBPage

func (c *Client) AddReplaceDBPage(ctx context.Context, appId, pageName string, pageId int, pageType PageType, pageBody string) (*AddReplaceDBPageResult, error)

AddReplaceDBPage adds a new code page or replaces an existing one.

QuickBase allows you to store various types of pages:

  • XSL stylesheets or HTML pages (PageTypeXSLOrHTML = 1)
  • Exact Forms for Word document integration (PageTypeExactForm = 3)

To add a new page, use pageName. To replace an existing page, use pageId. One of pageName or pageId must be provided (but not both).

Example (add new page):

result, err := xmlClient.AddReplaceDBPage(ctx, appId, "newpage.html", 0, PageTypeXSLOrHTML, "<html><body>Hello</body></html>")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Created page ID: %d\n", result.PageID)

Example (replace existing page):

result, err := xmlClient.AddReplaceDBPage(ctx, appId, "", 6, PageTypeXSLOrHTML, "<html><body>Updated</body></html>")

See: https://help.quickbase.com/docs/api-addreplacedbpage

func (*Client) AddUserToGroup

func (c *Client) AddUserToGroup(ctx context.Context, groupId, userId string, allowAdminAccess bool) error

AddUserToGroup adds a user to a group.

The user can be added as a regular member or as an admin (manager) of the group.

Example:

// Add user as regular member
err := xmlClient.AddUserToGroup(ctx, "1217.dgpt", "112149.bhsv", false)

// Add user as admin
err := xmlClient.AddUserToGroup(ctx, "1217.dgpt", "112149.bhsv", true)

See: https://help.quickbase.com/docs/api-addusertogroup

func (*Client) AddUserToRole

func (c *Client) AddUserToRole(ctx context.Context, appId, userId string, roleId int) error

AddUserToRole assigns a user to a role in the application.

You can call this multiple times to give a user multiple roles. After assigning, use SendInvitation to invite the user to the app.

Requires Basic Access with Sharing or Full Administration access. Users with Basic Access cannot add users to admin roles.

Example:

// Get user ID first
user, _ := xmlClient.GetUserInfo(ctx, "[email protected]")

// Assign them to role 10
err := xmlClient.AddUserToRole(ctx, appId, user.ID, 10)

See: https://help.quickbase.com/docs/api-addusertorole

func (*Client) ChangeGroupInfo

func (c *Client) ChangeGroupInfo(ctx context.Context, groupId, name, description, accountId string) error

ChangeGroupInfo modifies metadata for a group.

Any of name, description, or accountId can be empty to leave unchanged. At least one must be provided.

Note: The name may not contain spaces or punctuation.

Example:

err := xmlClient.ChangeGroupInfo(ctx, "1217.dgpt", "NewName", "New description", "")

See: https://help.quickbase.com/docs/api-changegroupinfo

func (*Client) ChangeManager

func (c *Client) ChangeManager(ctx context.Context, appId, newManagerEmail string) error

ChangeManager assigns a new manager for an application.

You must be an account admin or realm admin to use this call.

Example:

err := xmlClient.ChangeManager(ctx, appId, "[email protected]")

See: https://help.quickbase.com/docs/api-changemanager

func (*Client) ChangeRecordOwner

func (c *Client) ChangeRecordOwner(ctx context.Context, tableId string, recordId int, newOwner string) error

ChangeRecordOwner changes the owner of a record.

In QuickBase, the creator of a record is its owner. Some roles may restrict view/modify access to the record owner. Use this call to transfer ownership.

You must have Full Administration rights on the application.

The newOwner can be either:

  • A QuickBase username
  • An email address

Example:

// Change owner by record ID
err := xmlClient.ChangeRecordOwner(ctx, tableId, 123, "[email protected]")

See: https://help.quickbase.com/docs/api-changerecordowner

func (*Client) ChangeUserRole

func (c *Client) ChangeUserRole(ctx context.Context, appId, userId string, currentRoleId, newRoleId int) error

ChangeUserRole changes a user's role or disables their access.

This is preferred over RemoveUserFromRole when you want to keep the user in the app's user list but change/disable their access.

Pass newRoleId=0 to set the role to "None" (role ID 9), which disables access while keeping the user on the app's user list for future reinstatement.

Example:

// Change user from role 10 to role 11
err := xmlClient.ChangeUserRole(ctx, appId, "112149.bhsv", 10, 11)

// Disable access (set to None role)
err := xmlClient.ChangeUserRole(ctx, appId, "112149.bhsv", 10, 0)

See: https://help.quickbase.com/docs/api-changeuserrole

func (*Client) CopyGroup

func (c *Client) CopyGroup(ctx context.Context, groupId, name, description, accountId string) (*CopyGroupResult, error)

CopyGroup duplicates an existing group with the same users and subgroups.

The new group will have the specified name and a new ID.

Example:

result, err := xmlClient.CopyGroup(ctx, "1217.dgpt", "CopiedGroup", "Copy of original group", "")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Created group: %s (ID: %s)\n", result.Group.Name, result.Group.ID)

See: https://help.quickbase.com/docs/api-copygroup

func (*Client) CopyMasterDetail

func (c *Client) CopyMasterDetail(ctx context.Context, tableId string, opts CopyMasterDetailOptions) (*CopyMasterDetailResult, error)

CopyMasterDetail copies a master record with its detail records, or imports detail records from one master into another.

This is useful for: - Cloning a project with all its tasks - Creating templates from existing records - Copying detail records between master records

Example - Copy master and all details:

result, err := xmlClient.CopyMasterDetail(ctx, tableId, xml.CopyMasterDetailOptions{
    DestRecordID:   0,        // Create new master
    SourceRecordID: 1,        // Copy from record 1
    CopyFieldID:    6,        // Use field 6 for "Copy of [name]"
})
fmt.Printf("Created master record %d with %d total records\n",
    result.ParentRecordID, result.NumCreated)

Example - Import details into existing master:

result, err := xmlClient.CopyMasterDetail(ctx, tableId, xml.CopyMasterDetailOptions{
    DestRecordID:   3,        // Import into existing record 3
    SourceRecordID: 1,        // Copy details from record 1
})

See: https://help.quickbase.com/docs/api-copymasterdetail

func (*Client) CreateGroup

func (c *Client) CreateGroup(ctx context.Context, name, description, accountId string) (*CreateGroupResult, error)

CreateGroup creates a new group.

The group will be created with the caller as the group owner and first member. The caller must be the manager of the account where the group is created.

The name may not contain spaces or punctuation.

Example:

result, err := xmlClient.CreateGroup(ctx, "MarketingTeam", "Marketing department users", "")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Created group: %s (ID: %s)\n", result.Group.Name, result.Group.ID)

See: https://help.quickbase.com/docs/api-creategroup

func (*Client) DeleteGroup

func (c *Client) DeleteGroup(ctx context.Context, groupId string) error

DeleteGroup deletes a group.

Caution: Once a group has been deleted it cannot be restored.

Example:

err := xmlClient.DeleteGroup(ctx, "1217.dgpt")

See: https://help.quickbase.com/docs/api-deletegroup

func (*Client) DoQueryCount

func (c *Client) DoQueryCount(ctx context.Context, tableId, query string) (*DoQueryCountResult, error)

DoQueryCount returns the count of records matching a query without fetching data.

This is more efficient than running a full query when you only need to know how many records match. The query parameter uses the same syntax as API_DoQuery.

If a schema was configured with WithSchema, table aliases can be used.

Example:

// Count all records
result, err := xmlClient.DoQueryCount(ctx, tableId, "")
fmt.Printf("Total records: %d\n", result.NumMatches)

// Count records matching a filter
result, err := xmlClient.DoQueryCount(ctx, tableId, "{'7'.EX.'Active'}")
fmt.Printf("Active records: %d\n", result.NumMatches)

See: https://help.quickbase.com/docs/api-doquerycount

func (*Client) FieldAddChoices

func (c *Client) FieldAddChoices(ctx context.Context, tableId string, fieldId int, choices []string) (*FieldAddChoicesResult, error)

FieldAddChoices adds new choices to a multiple-choice or multi-select text field.

Constraints:

  • Choices are limited to 60 characters each
  • Maximum 100 choices per field
  • Duplicate choices are not added

Permissions:

  • Full Administration: Can add to any field
  • Other users: Can only add if field has "Allow users to create new choices" enabled

Example:

result, err := xmlClient.FieldAddChoices(ctx, tableId, 11, []string{"Red", "Green", "Blue"})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Added %d choices to field %s\n", result.NumAdded, result.FieldName)

See: https://help.quickbase.com/docs/api-fieldaddchoices

func (*Client) FieldRemoveChoices

func (c *Client) FieldRemoveChoices(ctx context.Context, tableId string, fieldId int, choices []string) (*FieldRemoveChoicesResult, error)

FieldRemoveChoices removes choices from a multiple-choice or multi-select text field.

You can remove any choices you created. You need Full Administration rights to remove choices created by others.

If some choices cannot be removed (don't exist or lack permission), other valid choices will still be removed. Check NumRemoved in the result to verify.

Example:

result, err := xmlClient.FieldRemoveChoices(ctx, tableId, 11, []string{"Red", "Blue"})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Removed %d choices from field %s\n", result.NumRemoved, result.FieldName)

See: https://help.quickbase.com/docs/api-fieldremovechoices

func (*Client) FindDBByName

func (c *Client) FindDBByName(ctx context.Context, name string, parentsOnly bool) (*FindDBByNameResult, error)

FindDBByName finds an app by its name.

Quickbase searches only apps you have access to. Multiple apps can have the same name, but this returns only the first match.

If the app has only one table, this returns the table dbid by default. Set parentsOnly=true to always get the app dbid.

Example:

result, err := xmlClient.FindDBByName(ctx, "My Project App", true)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("App DBID: %s\n", result.DBID)

See: https://help.quickbase.com/docs/api-finddbbyname

func (*Client) GenAddRecordForm

func (c *Client) GenAddRecordForm(ctx context.Context, tableId string, fields []GenAddRecordFormField) (string, error)

GenAddRecordForm returns an HTML form for adding a new record.

This returns the standard QuickBase "Add Record" page with optional pre-filled field values. The form includes edit fields and a Save button.

Note: When using this form, at least one field must be modified by the user for the record to save (pre-filled values alone aren't sufficient).

Example:

html, err := xmlClient.GenAddRecordForm(ctx, tableId, []xml.GenAddRecordFormField{
    {Name: "Email", Value: "[email protected]"},
    {ID: 7, Value: "Default Status"},
})
// Embed html in your page

See: https://help.quickbase.com/docs/api-genaddrecordform

func (*Client) GenResultsTable

func (c *Client) GenResultsTable(ctx context.Context, tableId string, opts GenResultsTableOptions) (string, error)

GenResultsTable returns query results formatted for embedding in HTML pages.

This is typically used to embed QuickBase data in external web pages. The output format depends on the Format option: - JHT: JavaScript function qdbWrite() containing HTML table - JSA: JavaScript array of data - CSV: Comma-separated values - TSV: Tab-separated values

Example:

html, err := xmlClient.GenResultsTable(ctx, tableId, xml.GenResultsTableOptions{
    QueryID: 5,
    CList:   "6.7.8",
    Format:  xml.GenResultsFormatJHT,
    Options: "num-10.sortorder-D",
})

See: https://help.quickbase.com/docs/api-genresultstable

func (*Client) GetAncestorInfo

func (c *Client) GetAncestorInfo(ctx context.Context, appId string) (*GetAncestorInfoResult, error)

GetAncestorInfo returns information about an app's copy lineage.

This call must be invoked on an app DBID (not a table DBID).

For first-generation copies, AncestorAppID and OldestAncestorAppID are the same. For grandchildren and later, AncestorAppID is the immediate parent and OldestAncestorAppID is the original template.

If a schema was configured with WithSchema, app aliases can be used.

Example:

info, err := xmlClient.GetAncestorInfo(ctx, appId)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Copied from: %s\n", info.AncestorAppID)
fmt.Printf("Original template: %s\n", info.OldestAncestorAppID)

See: https://help.quickbase.com/docs/api-getancestorinfo

func (*Client) GetAppDTMInfo

func (c *Client) GetAppDTMInfo(ctx context.Context, appId string) (*GetAppDTMInfoResult, error)

GetAppDTMInfo returns modification timestamps for an app and its tables.

This is a fast, unobtrusive call for detecting changes:

  • No authentication ticket required
  • Doesn't load the app into memory
  • Returns timestamps as Unix milliseconds

The response includes RequestNextAllowedTime to prevent abuse. Calling again before that time returns error code 77.

Note: The dbid must be an application ID, not a table ID.

If a schema was configured with WithSchema, app aliases can be used.

Example:

info, err := xmlClient.GetAppDTMInfo(ctx, appId)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("App last modified: %d\n", info.AppLastModifiedTime)
for _, table := range info.Tables {
    fmt.Printf("Table %s: schema=%d, records=%d\n",
        table.ID, table.LastModifiedTime, table.LastRecModTime)
}

See: https://help.quickbase.com/docs/api-getappdtminfo

func (*Client) GetDBInfo

func (c *Client) GetDBInfo(ctx context.Context, dbid string) (*GetDBInfoResult, error)

GetDBInfo returns metadata about an app or table.

This is useful for quick checks like:

  • Has the table changed since last sync? (compare LastModifiedTime)
  • How many records are in the table?
  • Who is the manager?

If a schema was configured with WithSchema, table aliases can be used.

Example:

info, err := xmlClient.GetDBInfo(ctx, tableId)
fmt.Printf("Table: %s\n", info.Name)
fmt.Printf("Records: %d\n", info.NumRecords)
fmt.Printf("Manager: %s\n", info.ManagerName)

See: https://help.quickbase.com/docs/api-getdbinfo

func (*Client) GetDBPage

func (c *Client) GetDBPage(ctx context.Context, appId, pageIdOrName string) (string, error)

GetDBPage retrieves a stored code page from QuickBase.

QuickBase allows you to store various types of pages, including user-guide pages, XSL stylesheets, HTML pages, and Exact Forms.

The pageIdOrName can be either a numeric page ID or a page name.

Example:

content, err := xmlClient.GetDBPage(ctx, appId, "3")
if err != nil {
    log.Fatal(err)
}
fmt.Println(content)

// Or by name
content, err := xmlClient.GetDBPage(ctx, appId, "mystylesheet.xsl")

See: https://help.quickbase.com/docs/api-getdbpage

func (*Client) GetDBVar

func (c *Client) GetDBVar(ctx context.Context, appId, varName string) (string, error)

GetDBVar returns the value of an application variable (DBVar).

DBVars are application-level variables that can be used in formulas and accessed via the API. You must have at least viewer access to the app.

Example:

value, err := xmlClient.GetDBVar(ctx, appId, "myVariable")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Variable value: %s\n", value)

See: https://help.quickbase.com/docs/api-getdbvar

func (*Client) GetGroupRole

func (c *Client) GetGroupRole(ctx context.Context, appId, groupId string) (*GetGroupRoleResult, error)

GetGroupRole returns the roles assigned to a group in an application.

Example:

result, err := xmlClient.GetGroupRole(ctx, appId, "1217.dgpt")
if err != nil {
    log.Fatal(err)
}
for _, role := range result.Roles {
    fmt.Printf("Role: %s (ID: %d)\n", role.Name, role.ID)
}

See: https://help.quickbase.com/docs/api-getgrouprole

func (*Client) GetNumRecords

func (c *Client) GetNumRecords(ctx context.Context, tableId string) (int, error)

GetNumRecords returns the total number of records in a table.

This is a lightweight call that only returns the count. For counting records that match a query, use DoQueryCount instead.

If a schema was configured with WithSchema, table aliases can be used.

Example:

count, err := xmlClient.GetNumRecords(ctx, tableId)
fmt.Printf("Total records: %d\n", count)

See: https://help.quickbase.com/docs/api-getnumrecords

func (*Client) GetRecordAsHTML

func (c *Client) GetRecordAsHTML(ctx context.Context, tableId string, opts GetRecordAsHTMLOptions) (string, error)

GetRecordAsHTML returns a record rendered as an HTML fragment.

This is useful for embedding a QuickBase record view in external pages. The HTML matches the layout of the specified form (or default form).

Example:

html, err := xmlClient.GetRecordAsHTML(ctx, tableId, xml.GetRecordAsHTMLOptions{
    RecordID: 123,
    FormID:   10, // optional: use specific form layout
})
// Embed html in your page

See: https://help.quickbase.com/docs/api-getrecordashtml

func (*Client) GetRecordInfo

func (c *Client) GetRecordInfo(ctx context.Context, tableId string, recordId int) (*GetRecordInfoResult, error)

GetRecordInfo returns a single record with full field metadata.

Unlike the JSON API which only returns field values by ID, this returns each field's name, type, value, and human-readable printable format. This is useful for building generic record viewers or debugging.

The tableId can be a table alias (if schema is configured) or a raw table ID. The recordId can be either the record ID (rid) or a value from a custom key field.

Example:

result, err := xmlClient.GetRecordInfo(ctx, tableId, 123)
fmt.Printf("Record %d has %d fields\n", result.RecordID, result.NumFields)
for _, field := range result.Fields {
    fmt.Printf("  %s (%s): %s\n", field.Name, field.Type, field.Value)
    if field.Printable != "" {
        fmt.Printf("    Formatted: %s\n", field.Printable)
    }
}

// With schema - access fields by alias:
result.Field("name").Value

See: https://help.quickbase.com/docs/api-getrecordinfo

func (*Client) GetRecordInfoByKey

func (c *Client) GetRecordInfoByKey(ctx context.Context, tableId string, keyValue string) (*GetRecordInfoResult, error)

GetRecordInfoByKey returns a single record using a custom key field value.

This is similar to GetRecordInfo but uses a key field value instead of record ID. The tableId can be a table alias (if schema is configured) or a raw table ID. The keyValue should be the value from the table's designated key field.

Example:

// If "Order Number" (field 6) is the key field
result, err := xmlClient.GetRecordInfoByKey(ctx, tableId, "ORD-12345")

// With schema - access fields by alias:
result.Field("name").Value

See: https://help.quickbase.com/docs/api-getrecordinfo

func (*Client) GetRoleInfo

func (c *Client) GetRoleInfo(ctx context.Context, appId string) (*GetRoleInfoResult, error)

GetRoleInfo returns all roles defined in a QuickBase application.

This calls the legacy API_GetRoleInfo XML endpoint. The appId should be the application-level dbid (not a table dbid).

If a schema was configured with WithSchema, app aliases can be used.

Example:

roles, err := xmlClient.GetRoleInfo(ctx, "bqxyz123")
for _, role := range roles.Roles {
    fmt.Printf("Role %d: %s (%s)\n", role.ID, role.Name, role.Access.Description)
}

See: https://help.quickbase.com/docs/api-getroleinfo

func (*Client) GetSchema

func (c *Client) GetSchema(ctx context.Context, dbid string) (*SchemaResult, error)

GetSchema returns comprehensive schema information for an app or table.

When called with an application dbid, returns app-level information including child table dbids and app variables.

When called with a table dbid, returns table-level information including field definitions, saved queries/reports, and table variables.

If a schema was configured with WithSchema, table aliases can be used as input and result helper methods become available:

// Use table alias instead of DBID
result, _ := xmlClient.GetSchema(ctx, "projects")

// Access fields by alias
result.Field("name").Label

Example (app-level):

schema, err := xmlClient.GetSchema(ctx, appId)
fmt.Printf("App: %s\n", schema.Table.Name)
for _, child := range schema.Table.ChildTables {
    fmt.Printf("  Table %s: %s\n", child.Name, child.DBID)
}

Example (table-level):

schema, err := xmlClient.GetSchema(ctx, tableId)
fmt.Printf("Table: %s\n", schema.Table.Name)
for _, field := range schema.Table.Fields {
    fmt.Printf("  Field %d: %s (%s)\n", field.ID, field.Label, field.FieldType)
}

See: https://help.quickbase.com/docs/api-getschema

func (*Client) GetUserInfo

func (c *Client) GetUserInfo(ctx context.Context, email string) (*UserInfo, error)

GetUserInfo returns information about a user by email address.

If email is empty, returns info about the current authenticated user. The email must belong to a user registered with QuickBase.

Use this to get a user ID before calling role assignment methods.

Example:

// Get info about a specific user
user, err := xmlClient.GetUserInfo(ctx, "[email protected]")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("User ID: %s, Name: %s %s\n", user.ID, user.FirstName, user.LastName)

// Get info about the current user
me, err := xmlClient.GetUserInfo(ctx, "")

See: https://help.quickbase.com/docs/api-getuserinfo

func (*Client) GetUserRole

func (c *Client) GetUserRole(ctx context.Context, appId, userId string, includeGroups bool) (*GetUserRoleResult, error)

GetUserRole returns the roles assigned to a specific user.

This calls the legacy API_GetUserRole XML endpoint. The appId should be the application-level dbid. The userId should be the user's QuickBase ID (e.g., "112149.bhsv").

If includeGroups is true, the response will include roles assigned via groups, with the Member field populated to indicate how the role was assigned.

Example:

result, err := xmlClient.GetUserRole(ctx, "bqxyz123", "112149.bhsv", true)
fmt.Printf("User: %s\n", result.UserName)
for _, role := range result.Roles {
    fmt.Printf("  Role: %s", role.Name)
    if role.Member != nil {
        fmt.Printf(" (via %s: %s)", role.Member.Type, role.Member.Name)
    }
    fmt.Println()
}

See: https://help.quickbase.com/docs/api-getuserrole

func (*Client) GetUsersInGroup

func (c *Client) GetUsersInGroup(ctx context.Context, groupId string, includeManagers bool) (*GetUsersInGroupResult, error)

GetUsersInGroup returns the list of users, managers, and subgroups in a group.

If includeManagers is true, both members and managers of the group are returned.

Example:

result, err := xmlClient.GetUsersInGroup(ctx, "1217.dgpt", true)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Group: %s\n", result.Name)
for _, user := range result.Users {
    fmt.Printf("  User: %s %s (%s)\n", user.FirstName, user.LastName, user.Email)
}

See: https://help.quickbase.com/docs/api-getusersingroup

func (*Client) GrantedDBs

func (c *Client) GrantedDBs(ctx context.Context, opts GrantedDBsOptions) (*GrantedDBsResult, error)

GrantedDBs returns a list of all apps and tables the user can access.

By default, this returns apps across all realms the user has access to. Use options to filter the results (e.g., only current realm, only admin access).

Child table names appear as "AppName:TableName" in the results.

Example:

// Get all accessible apps in this realm only
result, err := xmlClient.GrantedDBs(ctx, xml.GrantedDBsOptions{
    RealmAppsOnly: true,
})
for _, db := range result.Databases {
    fmt.Printf("%s: %s\n", db.DBID, db.Name)
}

// Get only apps where user is admin, with copy lineage
result, err := xmlClient.GrantedDBs(ctx, xml.GrantedDBsOptions{
    AdminOnly:        true,
    IncludeAncestors: true,
})

See: https://help.quickbase.com/docs/api-granteddbs

func (*Client) GrantedDBsForGroup

func (c *Client) GrantedDBsForGroup(ctx context.Context, groupId string) (*GrantedDBsForGroupResult, error)

GrantedDBsForGroup returns the list of databases (apps/tables) a group can access.

Example:

result, err := xmlClient.GrantedDBsForGroup(ctx, "1217.dgpt")
if err != nil {
    log.Fatal(err)
}
for _, db := range result.Databases {
    fmt.Printf("Database: %s (ID: %s)\n", db.Name, db.ID)
}

See: https://help.quickbase.com/docs/api-granteddbsforgroup

func (*Client) GrantedGroups

func (c *Client) GrantedGroups(ctx context.Context, userId string, adminOnly bool) (*GrantedGroupsResult, error)

GrantedGroups returns the list of groups a user has access to.

If adminOnly is true, only groups where the user has admin rights are returned.

Note: The caller must be a Realm admin to use this call.

Example:

result, err := xmlClient.GrantedGroups(ctx, "112149.bhsv", false)
if err != nil {
    log.Fatal(err)
}
for _, group := range result.Groups {
    fmt.Printf("Group: %s (ID: %s)\n", group.Name, group.ID)
}

See: https://help.quickbase.com/docs/api-grantedgroups

func (*Client) ImportFromCSV

func (c *Client) ImportFromCSV(ctx context.Context, tableId string, opts ImportFromCSVOptions) (*ImportFromCSVResult, error)

ImportFromCSV adds or updates multiple records from CSV data.

You can add new records and update existing records in the same request. For adds, leave the record ID column empty. For updates, include the key field (usually field 3, Record ID#) in the clist and CSV data.

Example - Add new records:

result, err := xmlClient.ImportFromCSV(ctx, tableId, xml.ImportFromCSVOptions{
    RecordsCSV: "Name,Status\nJohn,Active\nJane,Pending",
    CList:      "6.7",
    SkipFirst:  true,
})
fmt.Printf("Added %d records\n", result.NumRecsAdded)

Example - Update existing records:

result, err := xmlClient.ImportFromCSV(ctx, tableId, xml.ImportFromCSVOptions{
    RecordsCSV: "Record ID,Status\n1,Complete\n2,Active",
    CList:      "3.7",
    SkipFirst:  true,
})
fmt.Printf("Updated %d records\n", result.NumRecsUpdated)

See: https://help.quickbase.com/docs/api-importfromcsv

func (*Client) ProvisionUser

func (c *Client) ProvisionUser(ctx context.Context, appId, email, firstName, lastName string, roleId int) (*ProvisionUserResult, error)

ProvisionUser adds a new user who is not yet registered with QuickBase.

This call:

  • Starts a new user registration using the supplied email, first name, and last name
  • Gives application access to the user by adding them to the specified role

After calling ProvisionUser, use SendInvitation to invite the new user via email. When the user clicks the invitation, they'll complete their registration.

If the user is already registered with QuickBase, this call returns an error. Use GetUserInfo, AddUserToRole, and SendInvitation for existing users.

Permissions required:

  • Basic Access with Sharing: Can assign roles except Full Administration
  • Full Administration: Can assign any role

Example:

result, err := xmlClient.ProvisionUser(ctx, appId, "[email protected]", "John", "Doe", 11)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Provisioned user: %s\n", result.UserID)

// Send invitation email
err = xmlClient.SendInvitation(ctx, appId, result.UserID, "Welcome to our app!")

See: https://help.quickbase.com/docs/api-provisionuser

func (*Client) RemoveGroupFromRole

func (c *Client) RemoveGroupFromRole(ctx context.Context, appId, groupId string, roleId int, allRoles bool) error

RemoveGroupFromRole removes a group from a role in an application.

If allRoles is true, the group is removed from all roles in the app.

Example:

// Remove from specific role
err := xmlClient.RemoveGroupFromRole(ctx, appId, "1217.dgpt", 12, false)

// Remove from all roles
err := xmlClient.RemoveGroupFromRole(ctx, appId, "1217.dgpt", 0, true)

See: https://help.quickbase.com/docs/api-removegroupfromrole

func (*Client) RemoveUserFromGroup

func (c *Client) RemoveUserFromGroup(ctx context.Context, groupId, userId string) error

RemoveUserFromGroup removes a user from a group.

Note: You cannot remove the last manager from a group.

Example:

err := xmlClient.RemoveUserFromGroup(ctx, "1217.dgpt", "112149.bhsv")

See: https://help.quickbase.com/docs/api-removeuserfromgroup

func (*Client) RemoveUserFromRole

func (c *Client) RemoveUserFromRole(ctx context.Context, appId, userId string, roleId int) error

RemoveUserFromRole removes a user from a specific role.

If this is the user's only role, they lose all access to the app and are removed from the app's user list.

To temporarily disable access while keeping the user in the app, use ChangeUserRole with newRoleId=0 instead.

Example:

err := xmlClient.RemoveUserFromRole(ctx, appId, "112149.bhsv", 10)

See: https://help.quickbase.com/docs/api-removeuserfromrole

func (*Client) RunImport

func (c *Client) RunImport(ctx context.Context, tableId string, importId int) (*RunImportResult, error)

RunImport executes a saved import definition.

Saved imports are configured in the QuickBase UI under Import/Export. This allows you to run predefined imports from table to table.

To find the import ID:

  1. Open the application and click Import/Export
  2. Select "Import into a table from another table"
  3. Click the saved import name
  4. Look for &id=X in the URL - X is the import ID

Example:

result, err := xmlClient.RunImport(ctx, tableId, 10)
fmt.Println(result.ImportStatus) // "3 new records were created"

See: https://help.quickbase.com/docs/api-runimport

func (*Client) SendInvitation

func (c *Client) SendInvitation(ctx context.Context, appId, userId, userText string) error

SendInvitation sends an email invitation to a user for an application.

You can send an invitation to:

  • An existing QuickBase user granted access via AddUserToRole
  • A new user created via ProvisionUser

Example:

err := xmlClient.SendInvitation(ctx, appId, "112149.bhsv", "Welcome to our project tracker!")
if err != nil {
    log.Fatal(err)
}

See: https://help.quickbase.com/docs/api-sendinvitation

func (*Client) SetDBVar

func (c *Client) SetDBVar(ctx context.Context, appId, varName, value string) error

SetDBVar sets the value of an application variable (DBVar).

If the variable doesn't exist, it will be created. If it exists, the value will be overwritten. You must have full admin rights on the application.

Example:

err := xmlClient.SetDBVar(ctx, appId, "myVariable", "new value")
if err != nil {
    log.Fatal(err)
}

See: https://help.quickbase.com/docs/api-setdbvar

func (*Client) SetKeyField

func (c *Client) SetKeyField(ctx context.Context, tableId string, fieldId int) error

SetKeyField sets a field as the key field for a table.

Requirements for a key field:

  • Must be a unique field (Unique checkbox checked)
  • All values must be unique and non-blank
  • Cannot be a List-user, Multi-select text, or formula field

If you don't set a key field, QuickBase uses the built-in Record ID field.

You must have Full Administration rights on the application.

Example:

// Set field 6 as the key field
err := xmlClient.SetKeyField(ctx, tableId, 6)
if err != nil {
    log.Fatal(err)
}

See: https://help.quickbase.com/docs/api-setkeyfield

func (*Client) SignOut

func (c *Client) SignOut(ctx context.Context) error

SignOut clears the ticket cookie for API clients using cookie-based authentication.

This call is primarily for API client implementations that use the ticket cookie rather than the <ticket> parameter. It returns a null ticket cookie (named TICKET).

Important notes:

  • This does NOT invalidate any tickets
  • This does NOT log off the caller from QuickBase applications
  • Callers with a saved valid ticket can continue using it after SignOut
  • Some local applications may be unable to access QuickBase until API_Authenticate is called for a new ticket cookie

For most server-side SDK usage with user tokens, this call has no practical effect. It may be useful in edge cases involving browser-based ticket authentication.

Example:

err := xmlClient.SignOut(ctx)
if err != nil {
    log.Printf("SignOut failed: %v", err)
}

See: https://help.quickbase.com/docs/api-signout

func (*Client) UserRoles

func (c *Client) UserRoles(ctx context.Context, appId string) (*UserRolesResult, error)

UserRoles returns all users in an application and their role assignments.

This calls the legacy API_UserRoles XML endpoint. The appId should be the application-level dbid. You must have Basic Access with Sharing or Full Administration access to use this call.

If a schema was configured with WithSchema, app aliases can be used.

Example:

result, err := xmlClient.UserRoles(ctx, "bqxyz123")
for _, user := range result.Users {
    fmt.Printf("%s (%s):\n", user.Name, user.ID)
    for _, role := range user.Roles {
        fmt.Printf("  - %s\n", role.Name)
    }
}

See: https://help.quickbase.com/docs/api-userroles

func (*Client) WebhooksActivate

func (c *Client) WebhooksActivate(ctx context.Context, tableId string, actionIds []string) (*WebhooksActivateResult, error)

WebhooksActivate enables one or more webhooks.

Example:

result, err := xmlClient.WebhooksActivate(ctx, tableId, []string{"15", "16"})
fmt.Printf("Activated %d webhooks\n", result.NumChanged)

See: https://help.quickbase.com/docs/api-webhooks-activate

func (*Client) WebhooksCopy

func (c *Client) WebhooksCopy(ctx context.Context, tableId string, actionId string) (*WebhooksCopyResult, error)

WebhooksCopy duplicates an existing webhook.

Example:

result, err := xmlClient.WebhooksCopy(ctx, tableId, "15")
fmt.Printf("Created webhook copy with ID: %s\n", result.ActionID)

See: https://help.quickbase.com/docs/api-webhooks-copy

func (*Client) WebhooksCreate

func (c *Client) WebhooksCreate(ctx context.Context, tableId string, opts WebhooksCreateOptions) error

WebhooksCreate creates a new webhook for the table.

The webhook will fire based on the specified trigger conditions and send an HTTP request to the configured URL.

Example:

err := xmlClient.WebhooksCreate(ctx, tableId, xml.WebhooksCreateOptions{
    Label:        "Notify on new records",
    WebhookURL:   "https://myapp.example.com/webhook",
    WorkflowWhen: xml.WebhookTriggerAdd,
    MessageFormat: xml.WebhookFormatJSON,
    Headers: []xml.WebhookHeader{
        {Key: "Content-Type", Value: "application/json"},
    },
})

See: https://help.quickbase.com/docs/api-webhooks-create

func (*Client) WebhooksDeactivate

func (c *Client) WebhooksDeactivate(ctx context.Context, tableId string, actionIds []string) (*WebhooksDeactivateResult, error)

WebhooksDeactivate disables one or more webhooks.

Use WebhooksActivate to re-enable deactivated webhooks.

Example:

result, err := xmlClient.WebhooksDeactivate(ctx, tableId, []string{"15"})
fmt.Printf("Deactivated %d webhooks\n", result.NumChanged)

See: https://help.quickbase.com/docs/api-webhooks-deactivate

func (*Client) WebhooksDelete

func (c *Client) WebhooksDelete(ctx context.Context, tableId string, actionIds []string) (*WebhooksDeleteResult, error)

WebhooksDelete removes one or more webhooks.

Example:

result, err := xmlClient.WebhooksDelete(ctx, tableId, []string{"15", "16"})
fmt.Printf("Deleted %d webhooks\n", result.NumChanged)

See: https://help.quickbase.com/docs/api-webhooks-delete

func (*Client) WebhooksEdit

func (c *Client) WebhooksEdit(ctx context.Context, tableId string, opts WebhooksEditOptions) error

WebhooksEdit modifies an existing webhook.

Example:

err := xmlClient.WebhooksEdit(ctx, tableId, xml.WebhooksEditOptions{
    ActionID:      "15",
    Label:         "Updated webhook name",
    WebhookURL:    "https://myapp.example.com/new-endpoint",
    MessageFormat: xml.WebhookFormatJSON,
})

See: https://help.quickbase.com/docs/api-webhooks-edit

type CopyGroupResult

type CopyGroupResult struct {
	// Group is the newly created group
	Group Group
}

CopyGroupResult contains the response from API_CopyGroup.

type CopyMasterDetailOptions

type CopyMasterDetailOptions struct {
	// DestRecordID is the destination master record ID.
	// Set to 0 to copy the source master record and create a new one.
	// Set to an existing record ID to import detail records into that master.
	DestRecordID int

	// SourceRecordID is the source master record ID to copy from (required).
	SourceRecordID int

	// CopyFieldID is the field ID to use for naming the copied record.
	// Only required when DestRecordID is 0 (creating a new master record).
	// The new record name will be "Copy of [field value]".
	// Must be a text field, not a lookup/formula/unique field.
	CopyFieldID int

	// Recurse copies detail records of detail records recursively.
	// Supports up to 10 levels. Default is true.
	Recurse *bool

	// RelFieldIDs limits copying to specific relationships by report link field IDs.
	// Leave empty or set to "all" to copy all relationships.
	RelFieldIDs []int
}

CopyMasterDetailOptions configures the master-detail copy operation.

type CopyMasterDetailResult

type CopyMasterDetailResult struct {
	// ParentRecordID is the record ID of the destination master record.
	// Either the existing destrid or the newly created master record.
	ParentRecordID int

	// NumCreated is the total number of new records created.
	NumCreated int
}

CopyMasterDetailResult contains the response from API_CopyMasterDetail.

type CreateGroupResult

type CreateGroupResult struct {
	// Group is the created group
	Group Group
}

CreateGroupResult contains the response from API_CreateGroup.

type DoQueryCountResult

type DoQueryCountResult struct {
	// NumMatches is the number of records matching the query
	NumMatches int
}

DoQueryCountResult contains the response from API_DoQueryCount.

type Error

type Error struct {
	// Code is the QuickBase error code (e.g., 4 for "unauthorized")
	Code int

	// Text is the error text (e.g., "No error", "User not authorized")
	Text string

	// Detail provides additional context when available
	Detail string

	// Action is the API action that was called (e.g., "API_GetRoleInfo")
	Action string
}

Error represents an error returned by the QuickBase XML API.

func (*Error) Error

func (e *Error) Error() string

type FieldAddChoicesResult

type FieldAddChoicesResult struct {
	// FieldID is the field ID
	FieldID int

	// FieldName is the field label
	FieldName string

	// NumAdded is the number of choices successfully added
	NumAdded int
}

FieldAddChoicesResult contains the response from API_FieldAddChoices.

type FieldRemoveChoicesResult

type FieldRemoveChoicesResult struct {
	// FieldID is the field ID
	FieldID int

	// FieldName is the field label
	FieldName string

	// NumRemoved is the number of choices successfully removed
	NumRemoved int
}

FieldRemoveChoicesResult contains the response from API_FieldRemoveChoices.

type FindDBByNameResult

type FindDBByNameResult struct {
	// DBID is the database ID of the found app
	DBID string

	// Name is the app name (echoed from request)
	Name string
}

FindDBByNameResult contains the response from API_FindDBByName.

type GenAddRecordFormField

type GenAddRecordFormField struct {
	// ID is the field ID (use this or Name, not both)
	ID int

	// Name is the field name (use this or ID, not both)
	Name string

	// Value is the value to pre-fill
	Value string
}

GenAddRecordFormField represents a field to pre-fill in the add record form.

type GenResultsFormat

type GenResultsFormat string

GenResultsFormat specifies the output format for GenResultsTable.

const (
	// GenResultsFormatJHT returns HTML as a JavaScript function qdbWrite()
	GenResultsFormatJHT GenResultsFormat = "jht"

	// GenResultsFormatJHTNew returns HTML with newer CSS styles
	GenResultsFormatJHTNew GenResultsFormat = "jht_new"

	// GenResultsFormatJSA returns a JavaScript array
	GenResultsFormatJSA GenResultsFormat = "jsa"

	// GenResultsFormatCSV returns comma-separated values
	// Cannot be combined with num-n or skp-n options.
	GenResultsFormatCSV GenResultsFormat = "csv"

	// GenResultsFormatTSV returns tab-separated values
	// Cannot be combined with num-n or skp-n options.
	GenResultsFormatTSV GenResultsFormat = "tsv"
)

type GenResultsTableOptions

type GenResultsTableOptions struct {
	// Query is the query string (e.g., "{'7'.CT.'Active'}")
	// Use this OR QueryID OR QueryName, not multiple.
	Query string

	// QueryID is the ID of a saved query/report
	QueryID int

	// QueryName is the name of a saved query/report
	QueryName string

	// CList is a period-delimited list of field IDs to return.
	// Use "a" to return all fields.
	CList string

	// SList is a period-delimited list of field IDs for sorting.
	SList string

	// Format specifies the output format.
	// Use JHT for JavaScript function, JSA for JavaScript array,
	// CSV for comma-separated values, or TSV for tab-separated values.
	Format GenResultsFormat

	// Options is a period-delimited list of options:
	// - num-n: return max n records
	// - skp-n: skip first n records
	// - sortorder-A: ascending sort
	// - sortorder-D: descending sort
	// - ned: omit edit icons
	// - nvw: omit view icons
	// - nfg: omit new/updated icons
	// - phd: plain (non-hyperlinked) headers
	// - abs: absolute URLs
	// - onlynew: only records marked new/updated
	Options string
}

GenResultsTableOptions configures the results table generation.

type GetAncestorInfoResult

type GetAncestorInfoResult struct {
	// AncestorAppID is the DBID of the app this was copied from
	AncestorAppID string

	// OldestAncestorAppID is the DBID of the original app in the copy chain
	OldestAncestorAppID string
}

GetAncestorInfoResult contains the response from API_GetAncestorInfo.

type GetAppDTMInfoResult

type GetAppDTMInfoResult struct {
	// RequestTime is when the server received this request (Unix ms)
	RequestTime int64

	// RequestNextAllowedTime is the earliest time another request is allowed (Unix ms)
	RequestNextAllowedTime int64

	// AppLastModifiedTime is when the app schema was last modified (Unix ms)
	AppLastModifiedTime int64

	// AppLastRecModTime is when app records were last modified (Unix ms)
	AppLastRecModTime int64

	// Tables contains modification info for each table in the app
	Tables []TableDTMInfo
	// contains filtered or unexported fields
}

GetAppDTMInfoResult contains the response from API_GetAppDTMInfo.

func (*GetAppDTMInfoResult) Table

func (r *GetAppDTMInfoResult) Table(key string) *TableDTMInfo

Table returns a table by alias or DBID. If a schema was provided to the XML client, aliases are resolved first. Returns nil if not found.

Example:

// With schema
result.Table("projects").LastModifiedTime

// Without schema or for unknown tables
result.Table("bqxyz123").LastModifiedTime

type GetDBInfoResult

type GetDBInfoResult struct {
	// Name is the app/table name
	Name string

	// LastRecModTime is when a record was last modified (Unix ms)
	LastRecModTime int64

	// LastModifiedTime is when the table structure was last modified (Unix ms)
	LastModifiedTime int64

	// CreatedTime is when the table was created (Unix ms)
	CreatedTime int64

	// NumRecords is the total record count
	NumRecords int

	// ManagerID is the unique ID of the table manager
	ManagerID string

	// ManagerName is the name of the table manager
	ManagerName string

	// TimeZone is the app's time zone string
	TimeZone string
}

GetDBInfoResult contains the response from API_GetDBInfo.

type GetGroupRoleResult

type GetGroupRoleResult struct {
	// Roles is the list of roles assigned to the group in the app
	Roles []Role
}

GetGroupRoleResult contains the response from API_GetGroupRole.

type GetRecordAsHTMLOptions

type GetRecordAsHTMLOptions struct {
	// RecordID is the record ID to display (required)
	RecordID int

	// FormID is the optional form ID (dfid) to use for rendering.
	// If not specified, uses the default form layout.
	FormID int
}

GetRecordAsHTMLOptions configures the HTML record display.

type GetRecordInfoResult

type GetRecordInfoResult struct {
	// RecordID is the record's unique ID
	RecordID int

	// NumFields is the total number of fields in the record
	NumFields int

	// UpdateID is used for optimistic concurrency control
	UpdateID string

	// Fields contains all field values with their metadata
	Fields []RecordField
	// contains filtered or unexported fields
}

GetRecordInfoResult contains the response from API_GetRecordInfo.

func (*GetRecordInfoResult) Field

func (r *GetRecordInfoResult) Field(key string) *RecordField

Field returns a field by alias or ID string. If a schema was provided to the XML client, aliases are resolved first. Returns nil if not found.

Example:

// With schema
result.Field("name").Value   // Access by alias

// Without schema or for unknown fields
result.Field("6").Value      // Access by ID string

func (*GetRecordInfoResult) FieldByID

func (r *GetRecordInfoResult) FieldByID(id int) *RecordField

FieldByID returns a field by its numeric ID. Returns nil if not found.

type GetRoleInfoResult

type GetRoleInfoResult struct {
	// Roles is the list of all roles defined in the application
	Roles []Role
}

GetRoleInfoResult contains the response from API_GetRoleInfo.

type GetUserRoleResult

type GetUserRoleResult struct {
	// UserID is the user's QuickBase user ID
	UserID string

	// UserName is the user's display name
	UserName string

	// Roles is the list of roles assigned to this user
	Roles []UserRole
}

GetUserRoleResult contains the response from API_GetUserRole.

type GetUsersInGroupResult

type GetUsersInGroupResult struct {
	// GroupID is the group ID
	GroupID string

	// Name is the group name
	Name string

	// Description is the group description
	Description string

	// Users is the list of users in the group
	Users []GroupUser

	// Managers is the list of managers of the group (only if includeManagers=true)
	Managers []GroupManager

	// Subgroups is the list of subgroups in the group
	Subgroups []GroupSubgroup
}

GetUsersInGroupResult contains the response from API_GetUsersInGroup.

type GrantedDBInfo

type GrantedDBInfo struct {
	// DBID is the database/table ID
	DBID string

	// Name is the app/table name. Child tables appear as "AppName:TableName"
	Name string

	// AncestorAppID is the dbid of the app this was copied from (if any)
	AncestorAppID string

	// OldestAncestorAppID is the dbid of the original app in the copy chain
	OldestAncestorAppID string
}

GrantedDBInfo contains information about an accessible app or table.

type GrantedDBsForGroupResult

type GrantedDBsForGroupResult struct {
	// Databases is the list of databases the group can access
	Databases []GroupDBInfo
}

GrantedDBsForGroupResult contains the response from API_GrantedDBsForGroup.

type GrantedDBsOptions

type GrantedDBsOptions struct {
	// AdminOnly returns only tables where the user has admin privileges
	AdminOnly bool

	// ExcludeParents excludes application-level dbids (returns only child tables)
	ExcludeParents bool

	// WithEmbeddedTables includes child table dbids (default true)
	WithEmbeddedTables *bool

	// IncludeAncestors includes ancestor/oldest ancestor info in results
	IncludeAncestors bool

	// RealmAppsOnly returns only apps in the current realm (not all accessible realms)
	RealmAppsOnly bool
}

GrantedDBsOptions configures the GrantedDBs call.

type GrantedDBsResult

type GrantedDBsResult struct {
	// Databases is the list of accessible apps and tables
	Databases []GrantedDBInfo
	// contains filtered or unexported fields
}

GrantedDBsResult contains the response from API_GrantedDBs.

func (*GrantedDBsResult) Database

func (r *GrantedDBsResult) Database(key string) *GrantedDBInfo

Database returns a database by alias or DBID. If a schema was provided to the XML client, aliases are resolved first. Returns nil if not found.

Example:

// With schema
result.Database("projects").Name

// Without schema or for unknown tables
result.Database("bqxyz123").Name

type GrantedGroupsResult

type GrantedGroupsResult struct {
	// Groups is the list of groups the user has access to
	Groups []Group
}

GrantedGroupsResult contains the response from API_GrantedGroups.

type Group

type Group struct {
	// ID is the group ID (e.g., "1217.dgpt")
	ID string `xml:"id,attr"`

	// Name is the group name
	Name string `xml:"name"`

	// Description is the group description
	Description string `xml:"description"`

	// ManagedByUser indicates if the group is managed by the user
	ManagedByUser bool `xml:"managedByUser"`
}

Group represents a QuickBase group.

type GroupDBInfo

type GroupDBInfo struct {
	// Name is the database name
	Name string `xml:"dbname"`

	// ID is the database ID
	ID string `xml:"dbid"`
}

GroupDBInfo represents information about a database a group can access.

type GroupManager

type GroupManager struct {
	// ID is the manager's QuickBase user ID
	ID string `xml:"id,attr"`

	// FirstName is the manager's first name
	FirstName string `xml:"firstName"`

	// LastName is the manager's last name
	LastName string `xml:"lastName"`

	// Email is the manager's email address
	Email string `xml:"email"`

	// ScreenName is the manager's screen name (if set)
	ScreenName string `xml:"screenName"`

	// IsMember indicates if the manager is also a member of the group
	IsMember bool `xml:"isMember"`
}

GroupManager represents a manager of a group.

type GroupSubgroup

type GroupSubgroup struct {
	// ID is the subgroup's ID
	ID string `xml:"id,attr"`
}

GroupSubgroup represents a subgroup within a group.

type GroupUser

type GroupUser struct {
	// ID is the user's QuickBase user ID
	ID string `xml:"id,attr"`

	// FirstName is the user's first name
	FirstName string `xml:"firstName"`

	// LastName is the user's last name
	LastName string `xml:"lastName"`

	// Email is the user's email address
	Email string `xml:"email"`

	// ScreenName is the user's screen name (if set)
	ScreenName string `xml:"screenName"`

	// IsAdmin indicates if the user is an admin of the group
	IsAdmin bool `xml:"isAdmin"`
}

GroupUser represents a user in a group.

type ImportFromCSVOptions

type ImportFromCSVOptions struct {
	// RecordsCSV is the CSV data to import (required).
	// Use CDATA wrapper for complex data.
	RecordsCSV string

	// CList is a period-delimited list of field IDs mapping CSV columns to fields.
	// Use 0 to skip a column. Required when updating records or mapping specific fields.
	// Example: "6.7.8" maps columns 1-3 to fields 6, 7, 8.
	CList string

	// CListOutput specifies which fields to return in the response.
	// Period-delimited field IDs.
	CListOutput string

	// SkipFirst skips the first row (header row) if true.
	SkipFirst bool

	// DecimalPercent when true interprets 0.50 as 50% instead of 0.50%.
	DecimalPercent bool

	// MsInUTC when true interprets date/times as UTC milliseconds.
	MsInUTC bool

	// MergeFieldId uses a different field as the merge key instead of the table key.
	// The field must be unique.
	MergeFieldId int
}

ImportFromCSVOptions configures the CSV import operation.

type ImportFromCSVRecord

type ImportFromCSVRecord struct {
	// RecordID is the record's unique ID
	RecordID int

	// UpdateID is used for optimistic concurrency control in subsequent edits
	UpdateID string
}

ImportFromCSVRecord represents a record that was added or updated.

type ImportFromCSVResult

type ImportFromCSVResult struct {
	// NumRecsInput is the total number of records in the CSV
	NumRecsInput int

	// NumRecsAdded is the number of new records created
	NumRecsAdded int

	// NumRecsUpdated is the number of existing records updated
	NumRecsUpdated int

	// Records contains the record IDs and update IDs for all affected records
	Records []ImportFromCSVRecord
}

ImportFromCSVResult contains the response from API_ImportFromCSV.

type Option

type Option func(*Client)

Option configures the XML client.

func WithSchema

func WithSchema(schema *core.ResolvedSchema) Option

WithSchema configures the XML client to use schema aliases. When provided, table and field aliases can be used in method parameters, and result types gain helper methods for accessing data by alias.

Example:

schema := core.NewSchema().
    Table("projects", "bqxyz123").
        Field("id", 3).
        Field("name", 6).
        Field("status", 7).
    Build()

xmlClient := xml.New(qb, xml.WithSchema(core.ResolveSchema(schema)))

// Use table alias
result, _ := xmlClient.GetRecordInfo(ctx, "projects", 123)

// Access fields by alias
fmt.Println(result.Field("name").Value)

type PageType

type PageType int

PageType represents the type of a code page.

const (
	// PageTypeXSLOrHTML is for XSL stylesheets or HTML pages (type 1)
	PageTypeXSLOrHTML PageType = 1

	// PageTypeExactForm is for Exact Forms (type 3)
	PageTypeExactForm PageType = 3
)

type ProvisionUserResult

type ProvisionUserResult struct {
	// UserID is the user ID of the newly provisioned user
	UserID string
}

ProvisionUserResult contains the response from API_ProvisionUser.

type Query

type Query struct {
	// ID is the query ID
	ID int `xml:"id,attr"`

	// Name is the query name
	Name string `xml:"qyname"`

	// Type is the query type (e.g., "table")
	Type string `xml:"qytype"`

	// Description is the query description
	Description string `xml:"qydesc"`

	// Criteria is the query criteria/filter
	Criteria string `xml:"qycrit"`

	// ColumnList is the list of columns to display
	ColumnList string `xml:"qyclst"`

	// Options contains query options
	Options string `xml:"qyopts"`

	// SortList is the sort specification
	SortList string `xml:"qyslst"`

	// CalendarStartFieldList is for calendar views
	CalendarStartFieldList string `xml:"qycalst"`
}

Query represents a saved report/query.

type RecordField

type RecordField struct {
	// ID is the field ID
	ID int

	// Name is the field label/name
	Name string

	// Type is the field type (e.g., "Text", "Date", "File Attachment")
	Type string

	// Value is the raw field value
	Value string

	// Printable is the human-readable formatted value (e.g., formatted dates)
	// This may be empty for some field types.
	Printable string
}

RecordField represents a field value with its metadata from API_GetRecordInfo.

type Role

type Role struct {
	// ID is the unique identifier for the role
	ID int `xml:"id,attr"`

	// Name is the display name of the role
	Name string `xml:"name"`

	// Access describes the access level (e.g., "Basic Access", "Administrator")
	Access RoleAccess `xml:"access"`
}

Role represents a role defined in a QuickBase application.

type RoleAccess

type RoleAccess struct {
	// ID is the access level ID:
	//   1 = Administrator
	//   2 = Basic Access with Share
	//   3 = Basic Access
	ID int `xml:"id,attr"`

	// Description is the text description of the access level
	Description string `xml:",chardata"`
}

RoleAccess represents the access level of a role.

type RoleMember

type RoleMember struct {
	// Type is "user", "group", or "domainGroup"
	Type string `xml:"type,attr"`

	// Name is the display name of the member
	Name string `xml:",chardata"`
}

RoleMember describes how a role was assigned (directly or via group).

type RunImportResult

type RunImportResult struct {
	// ImportStatus describes the result, e.g., "3 new records were created"
	ImportStatus string
}

RunImportResult contains the response from API_RunImport.

type SchemaField

type SchemaField struct {
	// ID is the field ID
	ID int `xml:"id,attr"`

	// FieldType is the field type (e.g., "text", "numeric", "checkbox")
	FieldType string `xml:"field_type,attr"`

	// BaseType is the underlying storage type (e.g., "text", "int64", "bool")
	BaseType string `xml:"base_type,attr"`

	// Label is the field label/name
	Label string `xml:"label"`

	// FieldHelp is the help text shown to users
	FieldHelp string `xml:"fieldhelp"`

	// NoWrap indicates if text wrapping is disabled
	NoWrap int `xml:"nowrap"`

	// Bold indicates if the field is displayed in bold
	Bold int `xml:"bold"`

	// Required indicates if the field is required
	Required int `xml:"required"`

	// Unique indicates if values must be unique
	Unique int `xml:"unique"`

	// DoesDataCopy indicates if data copies to related records
	DoesDataCopy int `xml:"does_data_copy"`

	// Mode indicates the field mode
	Mode string `xml:"mode"`

	// DefaultValue is the default value for new records
	DefaultValue string `xml:"default_value"`

	// Formula is the formula (for formula fields)
	Formula string `xml:"formula"`

	// Choices contains the choices for multiple-choice fields
	Choices []string `xml:"choices>choice"`

	// SummaryFunction is for summary fields (e.g., "Total", "Average")
	SummaryFunction string `xml:"summaryFunction"`

	// SummaryTargetFieldID is the field being summarized
	SummaryTargetFieldID int `xml:"summaryTargetFid"`

	// SummaryReferenceFieldID is the relationship field
	SummaryReferenceFieldID int `xml:"summaryReferenceFid"`
}

SchemaField represents a field definition from the schema.

type SchemaResult

type SchemaResult struct {
	// TimeZone is the application's time zone (e.g., "(UTC-08:00) Pacific Time (US & Canada)")
	TimeZone string

	// DateFormat is the date format setting (e.g., "MM-DD-YYYY", "YYYY-MM-DD")
	DateFormat string

	// Table contains the schema information
	Table TableSchema
	// contains filtered or unexported fields
}

SchemaResult contains the response from API_GetSchema.

func (*SchemaResult) ChildTable

func (r *SchemaResult) ChildTable(key string) *ChildTable

ChildTable returns a child table by alias or DBID. If a schema was provided to the XML client, aliases are resolved first. Returns nil if not found.

Example:

// With schema
result.ChildTable("tasks").DBID

// By DBID
result.ChildTable("bqxyz123").DBID

func (*SchemaResult) Field

func (r *SchemaResult) Field(key string) *SchemaField

Field returns a field by alias or ID. If a schema was provided to the XML client, aliases are resolved first. Returns nil if not found.

Example:

// With schema
result.Field("name").Label

// By field ID (as string)
result.Field("6").Label

func (*SchemaResult) FieldByID

func (r *SchemaResult) FieldByID(id int) *SchemaField

FieldByID returns a field by its numeric ID. Returns nil if not found.

Example:

result.FieldByID(6).Label

type TableDTMInfo

type TableDTMInfo struct {
	// ID is the table DBID
	ID string

	// LastModifiedTime is when the table schema was last modified (Unix ms)
	LastModifiedTime int64

	// LastRecModTime is when records were last modified (Unix ms)
	LastRecModTime int64
}

TableDTMInfo contains modification timestamps for a table.

type TableOriginal

type TableOriginal struct {
	// AppID is the parent application's dbid
	AppID string `xml:"app_id"`

	// TableID is this table's dbid
	TableID string `xml:"table_id"`

	// CreatedDate is when the table was created (milliseconds since epoch)
	CreatedDate string `xml:"cre_date"`

	// ModifiedDate is when the table was last modified (milliseconds since epoch)
	ModifiedDate string `xml:"mod_date"`

	// NextRecordID is the ID that will be assigned to the next record
	NextRecordID int `xml:"next_record_id"`

	// NextFieldID is the ID that will be assigned to the next field
	NextFieldID int `xml:"next_field_id"`

	// NextQueryID is the ID that will be assigned to the next query
	NextQueryID int `xml:"next_query_id"`

	// DefaultSortFieldID is the default sort field
	DefaultSortFieldID int `xml:"def_sort_fid"`

	// DefaultSortOrder is the default sort order (1=ascending, -1=descending)
	DefaultSortOrder int `xml:"def_sort_order"`
}

TableOriginal contains metadata about a table's creation and state.

type TableSchema

type TableSchema struct {
	// Name is the table/app name
	Name string `xml:"name"`

	// Description is the table/app description
	Description string `xml:"desc"`

	// Original contains metadata about the table
	Original TableOriginal `xml:"original"`

	// Variables contains app-level variables (DBVars)
	Variables []Variable `xml:"variables>var"`

	// ChildTables contains child table dbids (only for app-level schema)
	ChildTables []ChildTable `xml:"chdbids>chdbid"`

	// Queries contains saved reports/queries
	Queries []Query `xml:"queries>query"`

	// Fields contains field definitions (only for table-level schema)
	Fields []SchemaField `xml:"fields>field"`
}

TableSchema contains schema information for an app or table.

type UserInfo

type UserInfo struct {
	// ID is the unique user ID (e.g., "112149.bhsv")
	ID string

	// FirstName is the user's first name
	FirstName string

	// LastName is the user's last name
	LastName string

	// Email is the user's email address
	Email string

	// Login is the user's login name (LDAP, screen name, or email)
	Login string

	// ScreenName is the user's QuickBase screen name
	ScreenName string

	// IsVerified indicates if the user's email is verified
	IsVerified bool

	// ExternalAuth indicates if user uses external authentication
	ExternalAuth bool
}

UserInfo contains information about a QuickBase user.

type UserRole

type UserRole struct {
	// ID is the role ID
	ID int `xml:"id,attr"`

	// Name is the role name
	Name string `xml:"name"`

	// Access is the access level
	Access RoleAccess `xml:"access"`

	// Member describes how this role was assigned (only present if inclgrps=1)
	Member *RoleMember `xml:"member"`
}

UserRole represents a role assigned to a user, with membership info.

type UserRolesResult

type UserRolesResult struct {
	// Users is the list of all users and their role assignments
	Users []UserWithRoles
}

UserRolesResult contains the response from API_UserRoles.

type UserWithRoles

type UserWithRoles struct {
	// ID is the user's QuickBase user ID (e.g., "112149.bhsv")
	ID string `xml:"id,attr"`

	// Type is "user" for individual users or "group" for groups
	Type string `xml:"type,attr"`

	// Name is the user's display name
	Name string `xml:"name"`

	// FirstName is the user's first name (may be empty for groups)
	FirstName string `xml:"firstName"`

	// LastName is the user's last name (may be empty for groups)
	LastName string `xml:"lastName"`

	// LastAccess is the timestamp of the user's last access (milliseconds since epoch)
	LastAccess string `xml:"lastAccess"`

	// LastAccessAppLocal is the human-readable last access time
	LastAccessAppLocal string `xml:"lastAccessAppLocal"`

	// Roles is the list of roles assigned to this user
	Roles []Role `xml:"roles>role"`
}

UserWithRoles represents a user and their assigned roles.

type Variable

type Variable struct {
	// Name is the variable name
	Name string `xml:"name,attr"`

	// Value is the variable value
	Value string `xml:",chardata"`
}

Variable represents a DBVar (database variable).

type WebhookHTTPVerb

type WebhookHTTPVerb string

WebhookHTTPVerb specifies the HTTP method for the webhook.

const (
	WebhookVerbPOST   WebhookHTTPVerb = "POST"
	WebhookVerbGET    WebhookHTTPVerb = "GET"
	WebhookVerbPUT    WebhookHTTPVerb = "PUT"
	WebhookVerbPATCH  WebhookHTTPVerb = "PATCH"
	WebhookVerbDELETE WebhookHTTPVerb = "DELETE"
)

type WebhookHeader

type WebhookHeader struct {
	Key   string
	Value string
}

WebhookHeader represents a key-value pair for webhook headers.

type WebhookMessageFormat

type WebhookMessageFormat string

WebhookMessageFormat specifies the format of the webhook payload.

const (
	WebhookFormatXML  WebhookMessageFormat = "XML"
	WebhookFormatJSON WebhookMessageFormat = "JSON"
	WebhookFormatRAW  WebhookMessageFormat = "RAW"
)

type WebhookTrigger

type WebhookTrigger string

WebhookTrigger specifies when a webhook should fire. Valid values are "a" (add), "d" (delete), "m" (modify), or any combination.

const (
	// WebhookTriggerAdd fires on record creation
	WebhookTriggerAdd WebhookTrigger = "a"
	// WebhookTriggerDelete fires on record deletion
	WebhookTriggerDelete WebhookTrigger = "d"
	// WebhookTriggerModify fires on record modification
	WebhookTriggerModify WebhookTrigger = "m"
	// WebhookTriggerAll fires on any change
	WebhookTriggerAll WebhookTrigger = "adm"
)

type WebhooksActivateResult

type WebhooksActivateResult struct {
	// NumChanged is the number of webhooks activated
	NumChanged int
}

WebhooksActivateResult contains the response from API_Webhooks_Activate.

type WebhooksCopyResult

type WebhooksCopyResult struct {
	// ActionID is the ID of the newly copied webhook
	ActionID string
}

WebhooksCopyResult contains the response from API_Webhooks_Copy.

type WebhooksCreateOptions

type WebhooksCreateOptions struct {
	// Label is a unique name for the webhook (required)
	Label string

	// WebhookURL is the endpoint URL (must start with https://) (required)
	WebhookURL string

	// Description of the webhook (optional)
	Description string

	// Query is filter criteria to trigger the webhook (optional)
	Query string

	// WorkflowWhen specifies when to trigger: "a" (add), "d" (delete), "m" (modify)
	// Can be combined, e.g., "adm" for all triggers. Default is "a".
	WorkflowWhen WebhookTrigger

	// Headers are key-value pairs for the webhook request headers
	Headers []WebhookHeader

	// Message is the payload of the webhook (empty by default)
	Message string

	// MessageFormat is the format of the payload: XML (default), JSON, or RAW
	MessageFormat WebhookMessageFormat

	// HTTPVerb specifies the HTTP method: POST (default), GET, PUT, PATCH, DELETE
	HTTPVerb WebhookHTTPVerb

	// TriggerFields limits the webhook to fire only when these field IDs change.
	// If empty, webhook fires on any field change.
	TriggerFields []int
}

WebhooksCreateOptions configures the webhook creation.

type WebhooksDeactivateResult

type WebhooksDeactivateResult struct {
	// NumChanged is the number of webhooks deactivated
	NumChanged int
}

WebhooksDeactivateResult contains the response from API_Webhooks_Deactivate.

type WebhooksDeleteResult

type WebhooksDeleteResult struct {
	// NumChanged is the number of webhooks deleted
	NumChanged int
}

WebhooksDeleteResult contains the response from API_Webhooks_Delete.

type WebhooksEditOptions

type WebhooksEditOptions struct {
	// ActionID is the ID of the webhook to edit (required)
	ActionID string

	// Label is a unique name for the webhook (required)
	Label string

	// WebhookURL is the endpoint URL (must start with https://) (required)
	WebhookURL string

	// Description of the webhook (optional)
	Description string

	// Query is filter criteria to trigger the webhook (optional)
	Query string

	// WorkflowWhen specifies when to trigger: "a" (add), "d" (delete), "m" (modify)
	WorkflowWhen WebhookTrigger

	// Headers are key-value pairs for the webhook request headers
	Headers []WebhookHeader

	// Message is the payload of the webhook
	Message string

	// MessageFormat is the format of the payload: XML, JSON, or RAW
	MessageFormat WebhookMessageFormat

	// HTTPVerb specifies the HTTP method: POST, GET, PUT, PATCH, DELETE
	HTTPVerb WebhookHTTPVerb

	// TriggerFields limits the webhook to fire only when these field IDs change.
	// Set to nil to keep existing, set to empty slice with ClearTriggerFields=true to clear.
	TriggerFields []int

	// ClearTriggerFields when true clears the field trigger criteria (fires on any field)
	ClearTriggerFields bool
}

WebhooksEditOptions configures webhook editing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL