Dart / Flutter SDK
Community Dart SDK in beta for Flutter and server-side Dart apps — async client over the same REST conventions.
| Status | beta — community-maintained, API may change |
| Requires | Dart 3+ / Flutter 3+ |
| Transport | package:http over the /v1 REST API |
Beta
The Dart package is not yet published to pub.dev. Until it ships, call the REST API directly with package:http — the pattern below mirrors what the final SDK will do.
#REST pattern today
sendafrica.dart
dart
import 'dart:convert';
import 'package:http/http.dart' as http;
class SendAfricaClient {
SendAfricaClient({required this.apiKey, this.baseUrl = 'https://api.sendafrica.online'});
final String apiKey;
final String baseUrl;
Future<Map<String, dynamic>> sendSms({
required String to,
required String message,
String? from,
}) async {
final res = await http.post(
Uri.parse('$baseUrl/v1/sms/'),
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json',
},
body: jsonEncode({
'to': to,
'message': message,
if (from != null) 'from': from,
}),
);
final body = jsonDecode(res.body) as Map<String, dynamic>;
if (!(body['success'] as bool)) {
throw Exception(body['error']);
}
return body['data'] as Map<String, dynamic>;
}
Future<int> balance() async {
final res = await http.get(
Uri.parse('$baseUrl/v1/credits/balance'),
headers: {'X-API-Key': apiKey},
);
final body = jsonDecode(res.body) as Map<String, dynamic>;
return (body['data'] as Map<String, dynamic>)['balance'] as int;
}
}
Future<void> main() async {
final client = SendAfricaClient(apiKey: 'SA-xxxxx');
final result = await client.sendSms(
to: '0712345678',
message: 'Welcome to SendAfrica',
);
print(${result['message_id']} ${result['status']});
}#Flutter notes
- Never ship your API key inside a mobile app — proxy sends through your backend instead.
- For OTP flows, expose a thin backend endpoint that calls
POST /v1/sms/server-side. - Use
compute()/isolates for bulk lists so the UI thread stays smooth.