On this section
Guide
Getting started with the Go SDK
Install the SDK, submit your first job, and poll it to completion — the submit-and-poll loop every VEED model shares.
Every VEED model works the same way: you submit a job, the API accepts it immediately, and you poll until it is done. This guide walks that loop end to end in Go, using Fabric 1.0 as the example — swap the client method and the inputs and the shape is identical for every other model.
Install
go get github.com/veedstudio/veed-sdk-goThe client reads VEED_API_KEY from the environment, so export the workspace key
you created in the dashboard:
export VEED_API_KEY="vp_..."The whole loop
package main
import (
"context"
"fmt"
"log"
veed "github.com/veedstudio/veed-sdk-go"
)
func main() {
client, err := veed.NewClient() // reads VEED_API_KEY
if err != nil {
log.Fatal(err)
}
job, err := client.Fabric.Generate(context.Background(), veed.FabricInput{
AudioURL: "https://static-assets.veed.io/api-examples/fabric-input.mp3",
ImageURL: "https://static-assets.veed.io/api-examples/fabric-input.png",
Resolution: "720p",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", job.Result)
}Generate submits the job and polls for you, honouring the interval the API
advertises (10 seconds for
this model), so you do not write a retry loop by hand. It takes a
context.Context, so a timeout or a cancelled request stops the polling too.
What this model takes
image_urlurlrequiredURL of the source image to animate.
audio_urlurlrequiredURL of the audio track to lip-sync to.
resolutionenumrequiredOutput video resolution.
720p480pBoth URLs must be publicly reachable over http(s) — the renderer fetches them itself, so a signed URL is fine but a localhost address is not.
resolution accepts 720p, 480p.
It is required, and the reference and playground both show 720p as the
example, which is the resolution most callers want.
Submitting and polling by hand
If you would rather drive the two calls yourself — a worker that persists the job
id across restarts, say — they are the two endpoints Generate wraps:
/v1/fabric-1.0
package main
import (
"context"
"fmt"
"log"
veed "github.com/veedstudio/veed-sdk-go"
)
func main() {
client, err := veed.NewClient() // reads VEED_API_KEY
if err != nil {
log.Fatal(err)
}
job, err := client.Fabric.Submit(context.Background(), veed.FabricInput{
AudioURL: "https://static-assets.veed.io/api-examples/fabric-input.mp3",
ImageURL: "https://static-assets.veed.io/api-examples/fabric-input.png",
Resolution: "720p",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(job.Status)
}/v1/fabric-1.0/{job_id}
package main
import (
"context"
"fmt"
"log"
veed "github.com/veedstudio/veed-sdk-go"
)
func main() {
client, err := veed.NewClient() // reads VEED_API_KEY
if err != nil {
log.Fatal(err)
}
job, err := client.Fabric.Get(context.Background(), "<job_id>")
if err != nil {
log.Fatal(err)
}
fmt.Println(job.Status)
}The job envelope is the same either way:
credits_chargedintegeroptionalCredits charged for the job. Present once the job is COMPLETED and the final charge is known.
credits_estimatedintegeroptionalCredits quoted before the job ran. Present only on the response that created the job. This is an estimate, not the price: the charged amount can be higher or lower.
Failure information. Present once the job has FAILED.
Show 3 nested fields
codeenumrequiredStable, machine-readable failure code for this job type.
input_validationcontent_moderationinvalid_fileaudio_too_longtransload_failedgeneration_failedtimeoutOptional structured failure details.
Show 3 nested fields
fieldstringoptionalDotted path to the offending input, when applicable.
messagestringrequiredHuman-readable explanation of this detail.
typestringrequiredThe category of this detail entry.
messagestringrequiredHuman-readable failure message.
job_iduuidrequiredStable identifier of the job and of the resource it produces.
The produced resource. Present once the job is COMPLETED.
Show 1 nested field
Generated lip-synced video.
Show 4 nested fields
content_typestringoptionalThe mime type of the file.
file_namestringoptionalThe name of the file.
file_sizeintegeroptionalThe size of the file in bytes.
urlstringrequiredThe URL where the file can be downloaded from.
statusenumrequiredCurrent lifecycle state of the job.
PROCESSINGCOMPLETEDFAILEDCANCELLEDStatus moves through PROCESSING, COMPLETED, FAILED, CANCELLED. Only
COMPLETED carries a Result; only FAILED carries an Error.
When a job fails
An accepted job can still fail while rendering, and the failure is reported on
the poll response rather than as a transport error — so err will be nil and
job.Status will be FAILED. Check both. The codes this model can return are input_validation, content_moderation, invalid_file, audio_too_long, transload_failed, generation_failed, timeout.
Treat anything other than COMPLETED and PROCESSING as terminal: a
CANCELLED or FAILED job will not change state again, and polling it further
only burns rate limit.
What it costs
It costs $0.08–$0.15 per second of the generated video, billed on the output rather than on the source image. The pricing page breaks that down per resolution.
Next
- Try the same inputs in the playground before you write any code
- Every other model follows this submit-and-poll shape — the reference pages list the inputs each one takes