Skip to Content

API 레퍼런스

io.deplite:sdk-android가 공개하는 모든 심볼을 시그니처와 함께 정리해요.
처음 보신다면 개요·Quickstart부터 읽어주세요.

진입 클래스

  • Deplite — External 모드 (Deplite를 호출)
  • DepliteAgent — Embedded 모드 (내 앱이 작업 노드)

이 페이지의 모든 suspend 함수는 4xx/5xx 응답 시 DepliteApiException, 401·403 응답 시 DepliteAuthException을 던질 수 있어요.
처리 방법은 예외 섹션을 참고해주세요.

class Deplite

public class Deplite( public val apiToken: String, public val baseUrl: String = DEFAULT_BASE_URL, okHttp: OkHttpClient = HttpClient.defaultOkHttp(), )

External 모드 클라이언트예요.

속성타입설명
apiTokenStringdpl_... 토큰 (로그 출력 금지)
baseUrlString기본 https://api.deplite.io/v1
triggersTriggers트리거 호출 매니저
filesFilesExternal 파일 매니저

Deplite.enroll(…)

@JvmStatic @JvmOverloads public suspend fun enroll( installCode: String, name: String, hostname: String? = null, os: String? = null, agentVersion: String? = null, baseUrl: String = DEFAULT_BASE_URL, okHttp: OkHttpClient = HttpClient.defaultOkHttp(), ): Enrollment

Embedded 모드용 1회 등록.
새 키쌍을 만들고 /agent/enroll을 호출해 Agent ID와 서버 공개키를 받아와요.

옵션타입필수설명
installCodeString대시보드에서 발급한 1회용 설치 코드 (en_...)
nameString에이전트 표시 이름
hostnameString?호스트네임
osString?"linux"·"android"
agentVersionString?에이전트 버전
baseUrlStringAPI 베이스 오버라이드

결과는 Enrollment로 받아오며, 포함된 identityprivateKey는 SDK가 보관하지 않으므로 호출 측이 암호화 후 저장하는 것을 추천드려요.

val enrollment = Deplite.enroll( installCode = INSTALL_CODE, name = "kiosk-seoul-01", ) secureStore.save(enrollment) // identity + privateKey

설치 코드는 1회용이라 enroll 성공 후 폐기돼요.
저장 실패에 대비해 반환값을 먼저 저장한 뒤 후속 로직을 시작하는 게 안전해요.

class Triggers — deplite.triggers

triggers.run(…)

public suspend fun run( triggerId: String, params: JsonElement? = null, workflowName: String? = null, ref: String? = null, debug: Boolean = false, idempotencyKey: String? = null, ): TriggerRunResult

POST /triggers/{triggerId}/run을 호출해 트리거를 실행해요.

옵션타입필수설명
triggerIdString트리거 UUID
paramsJsonElement?워크플로우에 전달될 페이로드 (buildJsonObject { ... })
workflowNameString?agent-scope 트리거에서는 필수
refString?git ref
debugBooleanverbose 실행
idempotencyKeyString?중복 실행 방지 키

호출 결과는 TriggerRunResult로 받아요.

val job = deplite.triggers.run( triggerId = TRIGGER_ID, params = buildJsonObject { put("ref", "main") put("actor", "sehyun") }, idempotencyKey = UUID.randomUUID().toString(), ) Log.i("Deplite", "${job.jobId} ${job.status}")

responseMode: sync로 만들어진 트리거여야 응답에 exitCode·output이 와요.
async 트리거는 jobId만 즉시 반환되고, 결과는 알림이나 워크플로우 콜백으로 받아야 해요.

class Files — deplite.files

External 모드에서 스토리지 파일을 다뤄요.
기본 CleanupRuleTtl(86_400) (24시간)이에요.

files.upload(…)

public suspend fun upload( file: File, cleanupRule: CleanupRule = CleanupRule.Ttl(86_400), filename: String? = null, contentType: String? = null, bindingId: String? = null, ): FileMeta

presign + PUT + complete를 하나의 호출로 처리해요(내부적으로 HTTP 3회).

옵션타입필수설명
fileFile업로드할 로컬 파일
cleanupRuleCleanupRule기본 24h TTL
filenameString?미지정 시 파일명 자동 추론
contentTypeString?MIME 타입
bindingIdString?토큰이 여러 binding을 허용할 때 필수

업로드가 끝나면 FileMeta 객체로 활성화된 파일 정보를 돌려줘요.

val uploaded = deplite.files.upload( file = File("/tmp/app.apk"), cleanupRule = CleanupRule.Ttl(3600), contentType = "application/vnd.android.package-archive", ) deplite.triggers.run( triggerId = TRIGGER_ID, params = buildJsonObject { put("apkFileId", uploaded.id) }, )

files.presignUpload(…)

public suspend fun presignUpload( cleanupRule: CleanupRule, filename: String? = null, contentType: String? = null, bindingId: String? = null, ): PresignedUpload

업로드 URL만 발급받아 직접 PUT 한 뒤 completeUpload를 호출하는 저수준 흐름이에요.
응답은 PresignedUpload로 받아오고, 이걸 가지고 직접 PUT 후 completeUpload를 호출하면 끝나요.

External 모드에서는 CleanupRule.OnJobEnd를 쓸 수 없어요(잡 컨텍스트가 없으므로).
Agent Files 전용이에요.

files.completeUpload / downloadUrl / download / get / list / delete

public suspend fun completeUpload(fileId: String): FileMeta public suspend fun downloadUrl(fileId: String): String public suspend fun download(fileId: String, to: File): File public suspend fun get(fileId: String): FileMeta public suspend fun list(bindingId: String? = null, status: String? = null): List<FileMeta> public suspend fun delete(fileId: String)

completeUpload는 PUT을 마친 뒤 파일을 활성 상태로 만들어요.
downloadUrl은 짧은 만료의 다운로드 URL을 발급하므로, 다운로드 직전에 새로 받는 게 안전해요.
downloadto로 직접 저장하며 상위 디렉토리는 자동으로 만들어줘요.
list는 토큰이 접근 가능한 binding 내 파일만 보여줘요.

class DepliteAgent

public class DepliteAgent( public val identity: AgentIdentity, privateKey: ByteArray, // 정확히 32바이트 okHttp: OkHttpClient = HttpClient.defaultOkHttp(), )

Embedded 모드 클라이언트예요.
enroll() 결과를 별도 저장소에서 꺼내 넘기면 돼요.

속성타입설명
identityAgentIdentity등록 시 받은 비밀이 아닌 신원
workflowsAgentWorkflows워크플로우 인벤토리 보고
jobsAgentJobsJob 로그·결과 보고
filesAgentFilesJob 범위 파일 매니저

생성자에 전달된 privateKey가 정확히 32바이트가 아니면 즉시 DepliteException이 던져져요.

agent.heartbeat()

public suspend fun heartbeat()

서명된 heartbeat를 1회 송신해요(추천 주기 30초).

agent.updateIdentity(…)

public suspend fun updateIdentity( hostname: String? = null, os: String? = null, agentVersion: String? = null, )

호스트네임·OS·버전 변경 시 PATCH로 알려요.

agent.events()

public fun events(): Flow<AgentEvent>

SSE 스트림을 코틀린 Flow로 노출해요.
서버 → Agent 명령(deploy 등)의 서명 검증은 SDK가 자동 처리하므로 호출 측은 이벤트 타입만 분기하면 돼요.

이벤트 종류는 AgentEvent를 참고해주세요.

agent.events().collect { ev -> when (ev) { is AgentEvent.Deploy -> handleDeploy(ev.payload) AgentEvent.SyncWorkflows -> reportWorkflows() AgentEvent.Revoke -> return@collect AgentEvent.Ping -> {} // keep-alive 무시 is AgentEvent.Unknown -> Log.w("Agent", "unknown: ${ev.name}") } }

전체 시나리오는 예제 페이지에 있어요.

class AgentJobs — agent.jobs

jobs.appendLogs(…)

public suspend fun appendLogs(jobId: String, items: List<LogItem>): Int

LogItem 배열을 한 번에 보내요.
서버가 실제로 수락한 라인 수가 돌아오고, 추천 배치 크기는 64KB 또는 1초 간격 중 빠른 쪽이에요.

jobs.reportResult(…)

public suspend fun reportResult(jobId: String, result: JobResult)

잡당 1회만 호출해요.
JobResult는 직접 만들기보다 팩토리(JobResult.success 등)를 추천드려요.

try { val output = runWorkflow(payload) agent.jobs.reportResult(payload.jobId, JobResult.success(output = output)) } catch (e: Exception) { agent.jobs.reportResult(payload.jobId, JobResult.failed(exitCode = 1, errorMessage = e.message)) }

class AgentFiles — agent.files

Job 컨텍스트 안에서 산출물 파일을 다뤄요.
기본 CleanupRuleOnJobEnd라 잡 종료 시 자동 정리돼요.
각 메소드의 옵션과 반환값은 External Files와 동일하고, 모든 호출에 jobId가 추가로 필요한 점만 달라요.

public suspend fun upload(jobId: String, file: File, ...): FileMeta public suspend fun presignUpload(jobId: String, ...): PresignedUpload public suspend fun complete(fileId: String): FileMeta public suspend fun downloadUrl(fileId: String): String public suspend fun download(fileId: String, to: File): File public suspend fun get(fileId: String): FileMeta public suspend fun delete(fileId: String)

External의 Files와 달리 모든 호출이 서명되고 jobId로 스코프돼요.
list는 노출되지 않아요.

class AgentWorkflows — agent.workflows

workflows.report(…)

public suspend fun report(workflows: List<WorkflowReport>): Int

서버에 알려진 워크플로우 인벤토리를 WorkflowReport 리스트로 완전히 교체해요.
보고된 워크플로우 수가 돌아와요.

실제 YAML·step run 명령·시크릿 값은 보내지 않는 것을 추천드려요.
이름·메타만 보고하는 게 격리 모델의 핵심이에요.

타입 참조

Enrollment

public data class Enrollment( val identity: AgentIdentity, val privateKey: ByteArray, // raw 32-byte 개인키 )

Deplite.enroll의 결과. 두 필드 모두 호출 측이 암호화 후 저장하는 것을 추천드려요.

AgentIdentity

public data class AgentIdentity( val agentId: String, val organizationId: String, val baseUrl: String, val serverPublicKeyPem: String, )

비밀이 아니라 일반 저장소에 두어도 무방해요.

AgentEvent

public sealed class AgentEvent { public data class Deploy(val payload: DeployPayload, val signature: String) : AgentEvent() public data object Revoke : AgentEvent() public data object SyncWorkflows : AgentEvent() public data object Ping : AgentEvent() public data class Unknown(val name: String, val data: String) : AgentEvent() }
타입의미
Deploy워크플로우 실행 명령 (payloadjobId·workflowName·params 등)
RevokeAgent 자격 회수
SyncWorkflows워크플로우 인벤토리 재보고 요청
Pingkeep-alive
Unknown알 수 없는 이벤트 또는 서명 검증 실패

DeployPayload

@Serializable public data class DeployPayload( val jobId: String, val workflowName: String, val debug: Boolean = false, val ref: String? = null, val params: JsonElement? = null, val issuedAt: Long = 0, val nonce: String = "", val force: Boolean = false, val forceReason: String? = null, )

TriggerRunResult

@Serializable public data class TriggerRunResult( val jobId: String, val status: String, val idempotent: Boolean = false, val timedOut: Boolean = false, val exitCode: Int? = null, val errorMessage: String? = null, val output: JsonElement? = null, val statusUrl: String? = null, )

CleanupRule

public sealed class CleanupRule { public data class Ttl(val ttlSeconds: Long) : CleanupRule() // 60s ≤ ttl ≤ 90일 public data object Persistent : CleanupRule() public data object OnJobEnd : CleanupRule() // Agent Files 전용 }

FileMeta

@Serializable public data class FileMeta( val id: String, val bindingId: String? = null, val jobId: String? = null, val filename: String? = null, val contentType: String? = null, val size: Long? = null, val status: String? = null, val cleanupRule: String? = null, val expiresAt: String? = null, val createdAt: String? = null, )

PresignedUpload

@Serializable public data class PresignedUpload( val fileId: String, val uploadUrl: String, val uploadHeaders: Map<String, String>? = null, val expiresInSeconds: Int? = null, )

LogItem

public enum class LogStream { Raw, System } public enum class LogLevel { Info, Warn, Error } public data class LogItem( val seq: Int, val stream: LogStream, val content: String, val stepName: String? = null, val level: LogLevel? = null, )

seq는 잡 안에서 단조 증가해야 해요.
Raw는 stdout/stderr 원본, System은 SDK 메타예요.

JobResult

public enum class JobStatus { Running, Success, Failed, Timeout, Rejected } public data class JobResult internal constructor( val status: JobStatus, val exitCode: Int? = null, val errorMessage: String? = null, val output: JsonElement? = null, val rejection: Rejection? = null, ) { public companion object { public fun running(): JobResult public fun success(exitCode: Int = 0, output: JsonElement? = null): JobResult public fun failed(exitCode: Int? = null, errorMessage: String? = null): JobResult public fun timeout(errorMessage: String? = null): JobResult public fun rejected(rejection: Rejection): JobResult } }

생성자가 internal이라 직접 만들지 말고 JobResult.success(...)·failed(...) 같은 팩토리를 사용해주세요.

Rejection

public data class Rejection( val reason: String, // 'rate_limited' | 'queue_full' | ... val limitType: String? = null, val retryAfterSeconds: Int? = null, val bypassedLimits: List<String> = emptyList(), )

WorkflowReport

@Serializable public data class WorkflowReport( val name: String, val verboseSteps: List<String> = emptyList(), val secretsKeys: List<String> = emptyList(), )

예외

DepliteException

public open class DepliteException( message: String, cause: Throwable? = null, ) : RuntimeException(message, cause)

네트워크·키·디스크 등 SDK 내부 오류의 베이스 클래스예요.

DepliteApiException

public open class DepliteApiException( public val statusCode: Int, public val body: String, ) : DepliteException("Deplite API error: $statusCode")

서버가 비-2xx 응답을 반환했을 때 던져져요(401·403 제외).

DepliteAuthException

public class DepliteAuthException( statusCode: Int, body: String, ) : DepliteApiException(statusCode, body)

401·403 전용. 토큰 회수·교체가 필요해요(재시도 무의미). Embedded는 재등록이 필요해요.

추천 처리 패턴

try { deplite.triggers.run(triggerId, params = buildJsonObject {}) } catch (e: DepliteAuthException) { // 토큰 회수·교체 필요 } catch (e: DepliteApiException) { if (e.statusCode == 429 || e.statusCode >= 500) { // 백오프 후 재시도 } } catch (e: DepliteException) { Log.e("Deplite", e.message, e.cause) }

관련 문서

최종 수정 일자: