AI 에이전트를 위한 API-first 이메일 인프라 LoftBox 의 공식 PHP SDK. TypeScript / Go / Rust SDK 와 1:1 풀 패리티이며, Laravel 통합을 기본 제공합니다.
- PHP
^8.1· PSR-12 · readonly DTO - HTTP 전송은 Guzzle 7
- Laravel auto-discovery (서비스 프로바이더 + 파사드)
composer require loftbox/sdkLaravel 사용 시 illuminate/support 가 이미 있으므로 추가 설치가 없으며,
서비스 프로바이더와 LoftBox 파사드가 auto-discovery 로 자동 등록됩니다.
use LoftBox\Client;
$client = new Client([
'apiKey' => getenv('LOFTBOX_API_KEY'),
// 'baseUrl' => 'https://api.loftbox.net', // 기본값
// 'timeout' => 30, // 초, 기본 30
]);
$agent = $client->agents->create([
'name' => 'Support Bot',
'slug' => 'support-bot',
]);
$mailbox = $client->mailboxes->create($agent->id, [
'localPart' => 'support',
]);
$message = $client->messages->send([
'mailboxId' => $mailbox->id,
'to' => ['customer@example.com'],
'subject' => '안녕하세요',
'bodyText' => '문의 주셔서 감사합니다.',
'idempotencyKey' => 'welcome-1', // 중복 발송 방지(선택)
]);
echo $message->id, ' ', $message->status;리소스는 프로퍼티($client->messages->send(...))와 메서드
($client->messages()->send(...)) 양쪽으로 접근할 수 있습니다.
.env 에 키를 설정합니다.
LOFTBOX_API_KEY=sk_live_...
# LOFTBOX_BASE_URL=https://api.loftbox.net
# LOFTBOX_TIMEOUT=30설정을 퍼블리시하려면(선택):
php artisan vendor:publish --tag=loftbox-config파사드로 호출:
use LoftBox\Laravel\LoftBox;
$message = LoftBox::messages()->send([
'mailboxId' => $mailboxId,
'to' => ['customer@example.com'],
'subject' => '안녕하세요',
'bodyText' => '본문',
]);또는 의존성 주입으로 LoftBox\Client 를 받습니다:
use LoftBox\Client;
class SupportController
{
public function __construct(private readonly Client $loftbox) {}
public function send()
{
return $this->loftbox->messages->send([/* ... */]);
}
}| 리소스 | 주요 메서드 |
|---|---|
auth |
signup, verifySignup |
agents |
create, get, list |
mailboxes |
create, listByAgent, listInbox, ackInbox |
messages |
send, get, list, addLabels, removeLabel, approve, reject |
threads |
list, listMessages |
webhooks |
create |
domains |
create, list, status |
suppressions |
list, create, remove |
inboundRules |
list, create, remove |
attachments |
listForMessage, presignedUrl |
목록 메서드는 LoftBox\Models\Page 를 반환합니다 (->data 배열 + ->nextCursor).
응답은 연관배열이 아니라 readonly DTO(LoftBox\Models\*)이며, 서버가 새 필드를
추가해도 무시되고 객체는 생존합니다.
LoftBox 는 수신 메일에 두 가지 안전 신호를 제공합니다.
수신 메시지에는 injectionScore(0~1, 높을수록 의심)와 발화한
injectionCategories(예: instruction_override)가 붙습니다. 신호 전용이며
차단이 아닙니다 — 에이전트에게 본문을 넘기기 전에 판단에 활용하세요.
$inbox = $client->mailboxes->listInbox($mailboxId);
foreach ($inbox->data as $msg) {
if (($msg->injectionScore ?? 0) >= 0.7) {
// 사람 검토로 라우팅하거나 LLM 컨텍스트에서 격리
}
}발신자 주소·도메인 단위로 수신을 통제합니다. mailboxId 를 지정하지 않으면
org 전체에 적용됩니다. block 매치 또는 allow 리스트 미매치 발신자는 수신 거부됩니다.
// 특정 도메인 차단
$client->inboundRules->create([
'ruleType' => 'block',
'patternType' => 'domain',
'pattern' => 'spam.example',
]);
// 신뢰 주소만 허용(allow 리스트)
$client->inboundRules->create([
'ruleType' => 'allow',
'patternType' => 'address',
'pattern' => 'partner@trusted.example',
'mailboxId' => $mailboxId,
]);
$rules = $client->inboundRules->list(['mailboxId' => $mailboxId]);
$client->inboundRules->remove($rules->data[0]->id);모든 API 오류는 LoftBox\Exceptions\LoftBoxException 또는 그 서브클래스로
발생하며 statusCode / body / requestId 를 보존합니다.
| 상태 | 예외 |
|---|---|
| 400 / 422 | ValidationException |
| 401 | AuthenticationException |
| 403 | PermissionException |
| 404 | NotFoundException |
| 409 | ConflictException |
| 429 | RateLimitException (getRetryAfterSecs()) |
use LoftBox\Exceptions\RateLimitException;
use LoftBox\Exceptions\LoftBoxException;
try {
$client->messages->send([/* ... */]);
} catch (RateLimitException $e) {
sleep($e->getRetryAfterSecs() ?? 1);
} catch (LoftBoxException $e) {
error_log($e->getMessage() . ' request-id=' . $e->getRequestId());
}composer install
vendor/bin/phpunit
vendor/bin/php-cs-fixer fix --dry-run --diffMIT