code: func (api *API) FragmentBlockData(ctx context.Context, body io.Reader) ([]byte, error) {
  	span, _ := tracing.StartSpanFromContext(ctx, "API.FragmentBlockData")
  	defer span.Finish()
  
  	if err := api.validate(apiFragmentBlockData); err != nil {
  		return nil, errors.Wrap(err, "validating api method")
  	}
  
  	reqBytes, err := ioutil.ReadAll(body)
  	if err != nil {
  		return nil, NewBadRequestError(errors.Wrap(err, "read body error"))
  	}
  	var req BlockDataRequest
  	if err := api.Serializer.Unmarshal(reqBytes, &req); err != nil {
  		return nil, NewBadRequestError(errors.Wrap(err, "unmarshal body error"))
  	}
  
  	// Retrieve fragment from holder.
  	f := api.holder.fragment(req.Index, req.Field, req.View, req.Shard)
  	if f == nil {
  		return nil, ErrFragmentNotFound
  	}
  
  	var resp = BlockDataResponse{}
  	resp.RowIDs, resp.ColumnIDs = f.blockData(int(req.Block))
  
  	// Encode response.
  	buf, err := api.Serializer.Marshal(&resp)
  	if err != nil {
  		return nil, errors.Wrap(err, "merge block response encoding error")
  	}
  
  	return buf, nil
  }
docs: // FragmentBlockData is an endpoint for internal usage. It is not guaranteed to
  // return anything useful. Currently it returns protobuf encoded row and column
  // ids from a "block" which is a subdivision of a fragment.