Polling an API endpoint with timeout using channels
How about this?
I used context.Context with the deadline which also gives control to the caller of poll if you want to cancel the poll before the deadline through CancelFunc. I do not have a full context of the problem here, but this should help you.

// PollStatus will keep 'pinging' the status API until timeout is reached or status returned is either successful or in error.
func (client *APIClient) PollStatus(ctx context.Context, id int, pollInterval time.Duration) (*Status, error) {
        ticker := time.NewTicker(pollInterval)
        defer ticker.Stop()
        tickerCounter := 0
        for {
            select {
            case &lt;-ctx.Done():
                return nil, ctx.Err()

            case tick := &lt;-ticker.C:
                status, err := client.GetStatus(id)
                tickerCounter++
                if err != nil {
                    return nil, err
                }

                log.Printf("tick #%d at '%ss', %s", tickerCounter, tick.Format("05"), status)
                if status.IsErrorStatus() {
                    return nil, errors.New("error while polling for status")
                }

                if status.IsCompletedStatus() {
                    return status, nil
                }

            }
        }

        return nil, errors.New("unable to get status")
  }

func someFunc() {
    log.Printf("polling status, id: %d", sid)
    ctx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Second)
    // Having cancelFunc here gives control if you want to cancel the poll before deadline
    // but for this instance, I'm just gonna defer cancel it
    defer cancelFunc()
    status, err := api.PollStatus(ctx, sid, 1*time.Second)
    if err != nil {
        log.Fatalf("PollStatus error: %+v", err)
    }

    log.Print(status)
}