PowerShell Invoke-RestMethod로 JSON POST 요청하기
해시테이블을 ConvertTo-Json -Depth로 바꾼 뒤 Bearer 헤더를 넣어 Invoke-RestMethod -Method Post -ContentType 'application/json'으로 보내세요.

PowerShell에서 JSON을 POST하려면 본문을 해시테이블로 만들고([ordered]@{}를 쓰면 키 순서가 유지됩니다) ConvertTo-Json -Depth 10으로 변환한 다음, -Headers에 Authorization: Bearer 헤더를 넣어 Invoke-RestMethod -Method Post -ContentType 'application/json' -Body $json으로 보내세요. -ContentType을 빼면 POST가 application/x-www-form-urlencoded로 전송되고, -Depth를 빼면 ConvertTo-Json은 중첩 객체를 두 단계까지만 포함합니다.
PowerShell 관련 내용은 Microsoft Learn의 PowerShell 7.5용 Invoke-RestMethod와 ConvertTo-Json 페이지, 그리고 출처에 나열한 Windows PowerShell 5.1 페이지에서, Sume 관련 내용은 Format 호출하기 (영문), 오류와 비용 (영문), 인증에서 가져왔습니다. 모두 2026-09-28에 확인했습니다. Sume에는 PowerShell 모듈이 없으며, 여기서는 HTTPS를 직접 호출합니다.
Invoke-RestMethod로 JSON 본문을 어떻게 POST하나요?
아래 PowerShell 7 스크립트는 Sume Format 실행을 시작합니다. 본문이 input 안에 product를 중첩하므로 -Depth가 중요합니다. Sume 자체의 생성 예제는 output_schema 안에 JSON Schema를 넣어 더 깊이 들어갑니다. -Depth는 최대 100까지 받으며, PowerShell 7.1 이상은 입력이 설정한 값보다 깊으면 경고를 표시합니다. Invoke-RestMethod는 JSON 응답을 객체로 바꾸므로 $run.data.id가 실행의 ID입니다.
[ordered]는 키를 작성한 순서대로 유지합니다. Microsoft의 about_Hash_Tables 페이지에 따르면 일반 해시테이블의 키 순서는 결정적이지 않습니다. 이 점은 다시 보낼 때 중요합니다. 현재 코드에서 Sume는 재전송된 input을 키가 전송된 순서 그대로 비교하므로, 같은 데이터라도 순서가 다르면 다른 본문으로 봅니다.
$json = [ordered]@{
instruction = 'Make the weekly promo video.'
input = [ordered]@{ product = [ordered]@{ name = 'Trail mug'; sku = 'MUG-01' } }
communication = @{ webhook_url = 'https://example.com/hooks/sume' }
} | ConvertTo-Json -Depth 10
$headers = @{
Authorization = "Bearer $env:SUME_API_KEY"
'Idempotency-Key' = 'weekly-promo-2026-w40'
}
$run = Invoke-RestMethod -Uri 'https://api.sume.com/v1/formats/acme/weekly-promo/runs' `
-Method Post -ContentType 'application/json' -Headers $headers -Body $json `
-TimeoutSec 30 -SkipHttpErrorCheck -StatusCodeVariable status
if ($status -ge 400) { throw "Sume $status $($run.error.code): $($run.error.message)" }
$run.data.id # 202: new run. 200: replay of the same key and body.Invoke-RestMethod로 Bearer 토큰은 어떻게 보내나요?
-Headers는 해시테이블을 받으므로 @{ Authorization = "Bearer $env:SUME_API_KEY" }는 모든 버전에서 동작합니다. PowerShell 6.0 이상에는 -Authentication Bearer도 있는데, 이 옵션은 -Token을 SecureString으로 요구하며 -Headers로 넘긴 Authorization 헤더를 모두 덮어씁니다. Windows PowerShell 5.1에는 -Authentication 매개변수가 없습니다.
- Sume는
Authorization: Bearer나x-api-key중 하나를 받으며, 둘 다 받지는 않습니다. 둘을 함께 실은 요청은Send only one API key credential.메시지와 함께401 unauthorized가 됩니다. - 키는 커밋되는 스크립트가 아니라 환경 변수나 시크릿 저장소에 두세요. Sume 문서는 API 키를 신뢰할 수 있는 서버, CI 시크릿 저장소, 개발자 머신에 두도록 안내합니다.
-TimeoutSec을 설정하세요. 기본값 0은 무기한 기다립니다.- Windows PowerShell 5.1에서
curl은Invoke-WebRequest의 별칭이므로, API 문서에서 복사한 curl 명령을 그곳에서 실행하면 curl이 실행되지 않습니다.
예외 대신 API의 JSON 오류를 어떻게 읽나요?
PowerShell 7에서 -SkipHttpErrorCheck를 쓰면 cmdlet이 HTTP 오류 상태를 무시하고 오류 응답을 성공한 것처럼 파이프라인에 기록하며, -StatusCodeVariable은 상태 코드를 저장합니다. 위 스크립트는 이 둘로 Sume의 오류 봉투(code, message, request_id, retryable, next_action)를 읽습니다. Windows PowerShell 5.1에는 두 매개변수가 모두 없으므로, 그곳에서는 try/catch로 오류를 잡으세요. 생성 단계의 4xx는 아무것도 실행되지 않았고 아무것도 청구되지 않았다는 뜻이므로, 재시도하지 말고 호출을 고치세요.
| Sume 응답 | PowerShell에서 흔한 원인 | 해결 방법 |
|---|---|---|
415 unsupported_media_type | -ContentType이 없어 POST가 application/x-www-form-urlencoded로 전송됨 | -ContentType 'application/json' |
401 unauthorized | 이 세션에서 $env:SUME_API_KEY가 비어 있거나, 자격 증명을 두 개 보냄 | 변수를 설정하고 자격 증명은 하나만 보내기 |
400 unknown_parameter | 해시테이블의 최상위 키 철자 오류 | details.errors[].suggestion 확인 |
409 idempotency_conflict | Idempotency-Key를 다른 본문과 함께, 또는 키가 다른 순서로 나온 input 해시테이블과 함께 재사용함 | 새 본문에는 새 키 사용, 본문은 [ordered]로 만들기 |
413 payload_too_large | 4 MiB를 넘는 본문 | 미디어는 URL로 보내기 |
POST에 -MaximumRetryCount를 써도 되나요?
멱등성 키 없이는 쓰지 마세요. -MaximumRetryCount는 상태 코드가 400에서 599 사이이거나 304일 때마다 재시도하므로, 성공할 수 없는 400이나 401도 다시 보내고 유료 생성 요청도 다시 보냅니다. 대기 시간은 -RetryIntervalSec으로 정하며, Retry-After가 있는 429를 받으면 cmdlet은 대신 그 시간만큼 기다립니다. Windows PowerShell 5.1에는 두 매개변수가 모두 없습니다. Sume 문서는 안전하지 않은 제출 요청을 Idempotency-Key 없이 재시도하지 말라고 안내합니다. 키가 있으면 다시 보내도 안전합니다.
- 같은 키, 같은 본문: 원래 실행과
idempotency_hit: true가 담긴200이 돌아옵니다. 두 번째 실행도, 두 번째 청구도 없습니다. - 첫 요청이 아직 처리 중일 때 같은 키:
409 idempotency_key_in_use가 돌아오며, 약 일 초 뒤에 재시도할 수 있습니다. - 키는 호출마다 새로 만든 GUID가 아니라 주차처럼 만들고 있는 대상에서 유도하세요. Sume 문서는 요청마다 무작위 키를 쓰면 헤더가 장식에 그친다고 말합니다. 키 설계는 AI 영상 API 멱등성 키에서 다룹니다.
출처
- Format 호출하기 (영문)
- 오류와 비용 (영문)
- 오류와 요청 한도 (영문)
- 인증
- Microsoft Learn: Invoke-RestMethod (PowerShell 7.5) (2026-09-28 확인)
- Microsoft Learn: Invoke-RestMethod (Windows PowerShell 5.1) (2026-09-28 확인)
- Microsoft Learn: ConvertTo-Json (PowerShell 7.5) (2026-09-28 확인)
- Microsoft Learn: about_Hash_Tables (PowerShell 7.5) (2026-09-28 확인)
- Microsoft Learn: Invoke-WebRequest (Windows PowerShell 5.1) (2026-09-28 확인)
관련 글
연동 카테고리의 다른 글
- Python requests 재시도: 백오프·Retry-After·POST
Requests는 기본적으로 재시도하지 않습니다. urllib3 Retry(백오프, status_forcelist)를 Session에 마운트하고, POST는 Idempotency-Key가 있을 때만 재시도하세요.
- Rails 웹훅: 컨트롤러에서 HMAC 서명 검증하기
request.raw_post를 읽고 그 액션만 CSRF를 건너뛴 뒤, OpenSSL::HMAC.hexdigest를 각 sume-v1 항목과 secure_compare로 비교하고 head 204로 응답하세요.
- Rust HMAC-SHA256: axum에서 웹훅 서명 검증하기
Rust에서는 hmac·sha2 크레이트로 HMAC-SHA256을 계산합니다. axum에서는 Bytes로 받아 timestamp.body에 MAC을 적용하고 각 항목을 verify_slice로 확인하세요.
- Sidekiq 재시도: 백오프, 재시도 횟수, 유료 API 호출
Sidekiq은 기본적으로 실패한 작업을 약 20일간 25번 재시도합니다. 횟수를 제한하고, sidekiq_retry_in으로 retry-after만큼 기다리고, 같은 Idempotency-Key를 재사용하세요.
작성자 Sume