or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcore-connector.mddata-processing.mddata-streams.mdindex.md

configuration.mddocs/

0

# Configuration & Authentication

1

2

Configuration specification and authentication setup for connecting to the Xero API. This includes credential management, tenant identification, and sync boundary configuration with comprehensive validation and security features.

3

4

## Capabilities

5

6

### Configuration Schema

7

8

Complete specification of required and optional configuration parameters for connecting to Xero's API.

9

10

```python { .api }

11

ConfigurationSpec = {

12

"type": "object",

13

"required": ["access_token", "tenant_id", "start_date"],

14

"additionalProperties": True,

15

"properties": {

16

"access_token": {

17

"type": "string",

18

"title": "Access Token",

19

"description": "Enter your Xero application's access token",

20

"airbyte_secret": True,

21

"order": 0

22

},

23

"tenant_id": {

24

"type": "string",

25

"title": "Tenant ID",

26

"description": "Enter your Xero organization's Tenant ID",

27

"airbyte_secret": True,

28

"order": 1

29

},

30

"start_date": {

31

"type": "string",

32

"title": "Start Date",

33

"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$",

34

"description": "UTC date and time in the format YYYY-MM-DDTHH:mm:ssZ. Any data with created_at before this data will not be synced.",

35

"examples": ["2022-03-01T00:00:00Z"],

36

"format": "date-time",

37

"order": 2

38

}

39

}

40

}

41

"""

42

Configuration schema for Xero source connector.

43

44

All three fields are required for successful connection:

45

- access_token: OAuth 2.0 bearer token for API authentication

46

- tenant_id: Xero organization identifier for multi-tenant access

47

- start_date: Defines the earliest date for incremental sync operations

48

"""

49

```

50

51

### Authentication Configuration

52

53

Details on Xero API authentication using OAuth 2.0 bearer tokens with tenant-specific access control.

54

55

```python { .api }

56

# Authentication headers automatically applied to all requests

57

AuthenticationHeaders = {

58

"Authorization": "Bearer {access_token}",

59

"Xero-Tenant-Id": "{tenant_id}",

60

"Accept": "application/json"

61

}

62

"""

63

HTTP headers used for Xero API authentication.

64

65

The connector automatically applies these headers to all API requests:

66

- Authorization: OAuth 2.0 bearer token authentication

67

- Xero-Tenant-Id: Required for multi-tenant Xero applications

68

- Accept: Specifies JSON response format preference

69

"""

70

71

# Base API configuration

72

APIConfiguration = {

73

"base_url": "https://api.xero.com/api.xro/2.0/",

74

"http_method": "GET",

75

"authenticator_type": "BearerAuthenticator"

76

}

77

"""

78

Core API configuration for Xero API endpoints.

79

80

All API calls use:

81

- HTTPS with Xero's standard API base URL

82

- GET method for data extraction (read-only operations)

83

- Bearer token authentication for security

84

"""

85

```

86

87

### Error Handling Configuration

88

89

Comprehensive error handling rules for different HTTP response scenarios with appropriate retry and failure strategies.

90

91

```python { .api }

92

ErrorHandlingRules = {

93

"401_unauthorized": {

94

"action": "FAIL",

95

"error_message": "Failed to authorize request. Please update your access token to continue using the source."

96

},

97

"403_forbidden": {

98

"action": "IGNORE",

99

"description": "Permission denied for specific records - skip and continue"

100

},

101

"429_rate_limited": {

102

"action": "RETRY",

103

"backoff_strategy": {

104

"type": "ConstantBackoffStrategy",

105

"backoff_time_in_seconds": 30

106

}

107

}

108

}

109

"""

110

HTTP error handling configuration for robust API interactions.

111

112

Response handling strategies:

113

- 401: Authentication failure - halt sync with clear error message

114

- 403: Permission denied - skip individual records, continue sync

115

- 429: Rate limit exceeded - retry after 30 second delay

116

"""

117

```

118

119

## Usage Examples

120

121

### Basic Configuration Setup

122

123

```python

124

# Minimum required configuration

125

config = {

126

"access_token": "your_xero_access_token_here",

127

"tenant_id": "your_xero_tenant_id_here",

128

"start_date": "2023-01-01T00:00:00Z"

129

}

130

131

# Validate configuration format

132

import re

133

from datetime import datetime

134

135

def validate_config(config):

136

"""Validate configuration parameters."""

137

errors = []

138

139

# Check required fields

140

required_fields = ["access_token", "tenant_id", "start_date"]

141

for field in required_fields:

142

if field not in config or not config[field]:

143

errors.append(f"Missing required field: {field}")

144

145

# Validate start_date format

146

if "start_date" in config:

147

pattern = r"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$"

148

if not re.match(pattern, config["start_date"]):

149

errors.append("start_date must be in format YYYY-MM-DDTHH:mm:ssZ")

150

151

return len(errors) == 0, errors

152

153

# Validate the configuration

154

is_valid, validation_errors = validate_config(config)

155

if is_valid:

156

print("Configuration is valid")

157

else:

158

print("Configuration errors:", validation_errors)

159

```

160

161

### Connection Testing

162

163

```python

164

from source_xero import SourceXero

165

import logging

166

167

def test_connection(config):

168

"""Test connection with proper error handling."""

169

source = SourceXero()

170

logger = logging.getLogger(__name__)

171

172

try:

173

is_connected, error_message = source.check_connection(logger, config)

174

175

if is_connected:

176

print("✓ Successfully connected to Xero API")

177

return True

178

else:

179

print(f"✗ Connection failed: {error_message}")

180

181

# Handle common error scenarios

182

if "authorize" in error_message.lower():

183

print(" → Check your access_token is valid and not expired")

184

elif "tenant" in error_message.lower():

185

print(" → Verify your tenant_id is correct")

186

187

return False

188

189

except Exception as e:

190

print(f"✗ Connection test error: {str(e)}")

191

return False

192

193

# Test with configuration

194

config = {

195

"access_token": "your_token",

196

"tenant_id": "your_tenant",

197

"start_date": "2023-01-01T00:00:00Z"

198

}

199

200

connection_success = test_connection(config)

201

```

202

203

### Advanced Configuration

204

205

```python

206

# Configuration with additional properties

207

advanced_config = {

208

# Required fields

209

"access_token": "your_xero_oauth_token",

210

"tenant_id": "12345678-1234-1234-1234-123456789012",

211

"start_date": "2023-01-01T00:00:00Z",

212

213

# Additional properties (connector supports extensibility)

214

"request_timeout": 30,

215

"max_retries": 3,

216

"log_level": "INFO"

217

}

218

219

# Start date configuration examples

220

start_date_examples = {

221

"recent_data": "2023-12-01T00:00:00Z", # Last month

222

"current_year": "2024-01-01T00:00:00Z", # Current year

223

"historical": "2020-01-01T00:00:00Z", # Historical data

224

"specific_time": "2023-06-15T14:30:00Z" # Specific timestamp

225

}

226

```

227

228

## Security Considerations

229

230

### Token Management

231

232

```python

233

import os

234

from pathlib import Path

235

236

def load_secure_config():

237

"""Load configuration from environment variables for security."""

238

config = {

239

"access_token": os.getenv("XERO_ACCESS_TOKEN"),

240

"tenant_id": os.getenv("XERO_TENANT_ID"),

241

"start_date": os.getenv("XERO_START_DATE", "2023-01-01T00:00:00Z")

242

}

243

244

# Validate all required environment variables are set

245

missing_vars = [key for key, value in config.items() if not value]

246

if missing_vars:

247

raise ValueError(f"Missing environment variables: {missing_vars}")

248

249

return config

250

251

# Usage with environment variables

252

# export XERO_ACCESS_TOKEN="your_token_here"

253

# export XERO_TENANT_ID="your_tenant_id_here"

254

# export XERO_START_DATE="2023-01-01T00:00:00Z"

255

256

secure_config = load_secure_config()

257

```

258

259

### Access Token Best Practices

260

261

- **Token Rotation**: Implement regular token refresh for long-running processes

262

- **Scope Limitation**: Use tokens with minimal required permissions

263

- **Secure Storage**: Store tokens in environment variables or secure vaults

264

- **Monitoring**: Log authentication failures for security monitoring

265

- **Expiry Handling**: Implement graceful handling of expired tokens

266

267

### Tenant ID Security

268

269

- **Validation**: Verify tenant IDs match expected format (UUID)

270

- **Access Control**: Ensure tokens have permission for specified tenant

271

- **Multi-tenant Apps**: Handle tenant switching in multi-organization scenarios

272

- **Audit Logging**: Track which tenants are accessed for compliance

273

274

## Troubleshooting

275

276

Common configuration issues and solutions:

277

278

```python

279

def diagnose_config_issues(config, error_message):

280

"""Diagnose common configuration problems."""

281

suggestions = []

282

283

if "401" in error_message or "unauthorized" in error_message.lower():

284

suggestions.extend([

285

"Verify access_token is valid and not expired",

286

"Check token has required scopes: accounting.transactions.read, accounting.contacts.read",

287

"Ensure token was generated for the correct Xero application"

288

])

289

290

if "403" in error_message or "forbidden" in error_message.lower():

291

suggestions.extend([

292

"Verify tenant_id matches the organization you have access to",

293

"Check your Xero application has permission to access this tenant",

294

"Ensure the organization subscription includes required features"

295

])

296

297

if "tenant" in error_message.lower():

298

suggestions.extend([

299

"Verify tenant_id is in correct UUID format",

300

"Check tenant_id matches an organization you have access to",

301

"Try using the organization's short code instead if supported"

302

])

303

304

return suggestions

305

306

# Example usage

307

error_msg = "Failed to authorize request"

308

suggestions = diagnose_config_issues(config, error_msg)

309

for suggestion in suggestions:

310

print(f" → {suggestion}")

311

```